Рейтинг:
18
Dave Kreskowiak
Вы определяете контекст где-то еще? Он должен быть создан внутри DoWork, где происходит вся ваша работа с базой данных.
Если вы определяете глобальный контекст, который будет использоваться везде в вашем классе, вы делаете это неправильно, и это может создать для вас проблемы, которые являются королевской занозой в заднице, чтобы выследить.
Там, где вы работаете с базой данных, шаблон должен быть открыт контекст как можно позже, выполнять работу с базой данных и закрывать/утилизировать контекст как можно раньше.
Кроме того, ваш блок try/catch нигде не сообщает об ошибке, поэтому он скрывает исключение и детали, которые его вызвали. Это значительно усложняет поиск и устранение неисправностей, таких как проблема, с которой вы столкнулись сейчас.
Для целей отладки либо избавьтесь от блока try/catch, либо зарегистрируйте сведения об исключении где-нибудь, где вы можете их прочитать.
Priya-Kiko
Спасибо, что пролили немного света. Контекст действительно был определен "где-то еще" глобально. Что касается отчетов об ошибках, то у нас есть процедура обработки ошибок. Это всего лишь пример кода.
Dave Kreskowiak
Ваш "пример кода" не помогает решить проблему.
Причина, по которой "глобальный" контекст является проблемой, заключается в том, что вы не можете иметь два метода, использующих контекст одновременно. Например, наличие одного метода, возвращающего записи из перечисления, и наличие второго метода, пытающегося использовать контекст для изменения записей, не будут работать и будут выбрасываться.
Priya-Kiko
Хорошо. Может быть, вы посоветуете мне вообще избавиться от глобального контекста?
Разве не правильно ограничивать глобальный контекст только операциями чтения для отчетов и т. д. и окончательно избавляться от него при выходе, в то время как мы используем другой локальный контекстный объект внутри using() для вставки, обновления и удаления БД ??
Теперь изменили код обновления следующим образом :
DbUpdateJob_DoWork(отправитель объекта, DoWorkEventArgs e)
{
использование (MyContext dbContext = new MyContext())
{
использование (DbContextTransaction mdbtrans =
DbContext можно.Базы данных.BeginTransaction(Уровень Изоляции.Упорядочиваемый))
{
пробовать
{
--- операции БД с entityA - 1 ( вставка записей )
DbUpdateJob.ReportProgress(20);
--- операции с БД с entityB - 2 ( вставка записей)
DbUpdateJob.ReportProgress(40);
--- операции БД с entityC - 3 (обновление записей )
DbUpdateJob.ReportProgress(60);
--- операции с БД wiwth entityD - 4 (вставка записей)
DbUpdateJob.ReportProgress(80);
DbContext можно.Метод SaveChanges();
мдбтранс.Совершать();
DbUpdateJob.ReportProgress(100);
}
поймать(исключение бывший)
{
мдбтранс.Отмена();
DbUpdateJob.ReportProgress(0);
}
}
}
}
DbUpdateJob_ProgressChanged(отправитель объекта, ProgressChangedEventArgs e)
{
pbupdate.Значение = e.ProgressPercentage;
если (например, ProgressPercentage == 0)
Ящик для сообщений.Показать(например,сообщение);
если (например, ProgressPercentage == 100)
Ящик для сообщений.Шоу("Успех..!!");
}
После создания локального контекста откат происходит совершенно нормально. Еще раз благодарю вас.
Dave Kreskowiak
Избавьтесь от глобального контекста. То, о чем вы не думаете, - это то, что вы захватываете ресурс подключения на SQL server для жизни вашего объекта BackgroundWorker. Ресурсы подключения на SQL server ограничены. Если ваш класс держит соединение открытым в течение всей жизни экземпляра, это плохо.
Всегда открывайте как можно позже, делайте свою работу как можно быстрее и закрывайте/избавляйтесь от контекста как можно раньше.
Priya-Kiko
Хорошо. Спасибо.
Dave Kreskowiak
Причина, по которой глобальный контекст так плох, заключается в разделении интересов и контроле времени жизни объекта. Используя глобальный контекст на уровне класса, вы предоставляете вызывающему объекту контроль над временем жизни контекста, а не над классом, который его использует. Это наоборот. Класс, использующий контекст, который выполняет работу с базой данных, должен иметь контроль над временем жизни контекста.
Priya-Kiko
Я получил очень ясную картину из вашего подробного объяснения, которое также привело к нескольким дальнейшим чтениям. Большое спасибо за это. Удалили глобальный контекст и, как вы предложили, объявили его внутри using (), где когда-либо выполняется работа с базой данных. Спасибо снова.