Это немного позер, и я надеюсь, что вы найдете эту сложную проблему, как интересно, как я ... :)Предотвращение рекурсии во время DataContext.SubmitChanges()
У меня есть подкласс DataContext
под названием MyDataContext
, в котором я переопределен метод SubmitChanges()
с некоторым кодом вида:
BeginTransaction(); // my own implementation
IList<object> Updates = GetChangeSet().Updates;
foreach (object obj in Updates) {
MyClass mc = obj as MyClass;
if (mc != null)
mc.BeforeUpdate(); // virtual method in MyClass to allow pre-save processing
}
// This is followed by similar code for the Deletes and Inserts, then:
base.SubmitChanges();
// Then do post-save processing...
foreach (object obj in Updates) {
MyClass mc = obj as MyClass;
if (mc != null)
mc.AfterUpdate(); // virtual method in MyClass to allow post-save processing
}
// similar code for Inserts and Deletes
// ...
CommitTransaction();
// obviously all enclosed in a try-catch block where the catch does a rollback
до сих пор, так хорошо. Но есть небольшая проблема, которая возникает, если реализация MyClass
вызывает SubmitChanges()
в своем методе BeforeUpdate()
или AfterUpdate()
. Теперь у нас есть рекурсия, которая может привести к переполнению стека.
Один из способов, с которым я решил работать, - это иметь переменную, блокирующую рекурсию, в начале SubmitChanges()
. Но что делать, если сохранение заблокировано? Я не могу открутить его в новую нить; вызывающий поток может требовать, чтобы вызов SubmitChanges()
был синхронным, например. если ему нужен доступ к свойству auto-number сразу после сохранения.
Дополнительным фактором является то, что если какие-либо объекты изменяются в процессе пре- или пост-обработки, я также хочу ихBeforeSave()
и AfterSave()
методы можно назвать.
Есть ли какой-нибудь умный способ сделать это аккуратно и правильно?
Оно должно быть только меня, но я не вижу причин, почему вы не можете использовать переменная, блокирующая рекурсию ...? – ShdNx
ShdNx - потому что, если есть рекурсия, это означает, что я на самом деле * хочу * сделать другое сохранение; Я не хочу блокировать второе спасение. Но я также не хочу бесконечной рекурсии ... –
Хорошо, отправил ответ. – ShdNx