Операция не может быть завершена, потому что DbContext был расположен в объекте - PullRequest
0 голосов
/ 06 ноября 2018
private void FunctionA(int t)
{
    var c=Context.Entities.TableStudent.Where(x => x.StudentBranch ==t).ToList();

using(var db=Context.Entities)
{
   foreach (var q in c)
{
    var cb=Context.Entities.Student...
     .
     .
     .
}
DbContext.Entities.SaveChanges();
}
}
c.ForEach(a => a.Situation=true);
DbContext.Entities.SaveChanges();
}

Я беру DbContext.Entities.SaveChanges (); строка дает ошибку. Эта ошибка

Операция не может быть завершена из-за удаления DbContext.

Как я могу сделать это с этой ошибкой. .

1 Ответ

0 голосов
/ 07 ноября 2018

Хорошо, сначала продолжим чтение / изучение блоков IDisposable, using(), а также соглашений об именах. Вы не делаете себе никаких одолжений, усложняя понимание своего кода, пытаясь вспомнить, что такое «a», «c» и т. Д., Просто чтобы сэкономить несколько секунд, набирая осмысленное имя.

Я довольно удивлен, что код, который вы вставили, на самом деле скомпилируется, но не зная, что такое «Context» и «DbContext» (пространства имен, статические классы ??) ...

У вас будет класс, который расширяет DbContext EF, я назову его «MyContext» .. Т.е.

public class MyContext : DbContext
{
}

Внутри этого класса вы объявите DbSets и, вероятно, переопределенный метод OnModelCreating() для обработки любой нетривиальной конфигурации для ваших сущностей.

public class MyContext : DbContext
{
    public DbSet<TableStudent> Students{ get; set; }
}

Этот класс никогда не должен помечаться как "статический".

Затем, с помощью вашего кода для манипулирования студентами, связанными сущностями и / или другими сущностями, в которых у вас есть DbSets в DbContext, вы захотите ограничить продолжительность жизни DbContext и убедиться, что все операции с этими сущностями происходят в течение этой продолжительности жизни. Эта продолжительность жизни ограничена блоком using(). Как только код покидает блок using, DbContext удаляется. Это означает, что любые ссылки отложенной загрузки, сделанные сущностями , не будут работать .

using (var myContext = new MyContext())
{
    var students= myContext.Students.Where(x => x.StudentBranch == studentBranch).ToList();

   foreach (var student in students)
   {
     // .. logic...
     student.Situation = true;
   }
   myContext.SaveChanges();
}
// After this point, it is unwise/unsafe to "use" any reference to students. 

Делайте то, что вам нужно сделать в рамках блока использования. Если вам нужно передать данные ученика извне, например, для возврата из вызова метода, скопируйте значения в обычный объект C # (ViewModel или DTO) и верните его. Доступ к сущностям вне области действия DbContext приведет к ошибкам, так как был удален контекст, в который был загружен учащийся. Даже в тех случаях, когда область действия остается активной (например, с помощью статического контекста [плохо!] Или определения контекста веб-запроса с помощью контейнера IoC, вы можете избежать ошибок, но создать непреднамеренные проблемы с производительностью из-за отложенной загрузки.

SaveChanges - это то, что обычно нужно вызывать только один раз в пределах жизненного диапазона DbContext. Когда EF настроен на знание отношений между сущностями, он будет управлять связыванием таких вещей, как внешние ключи, между сущностями, даже новыми созданными вами сущностями. Одна распространенная точка паники, которую достигают люди, - это сценарий «курица и яйцо», где я хочу создать сущность с детьми, но детям нужен родительский идентификатор, который не будет существовать, пока не будет вызван SaveChanges. До тех пор, пока родительские и дочерние отношения отображаются правильно, EF будет разрешать это автоматически при вызове SaveChanges при условии, что дочерние элементы были добавлены в дочернюю коллекцию родителя. SaveChanges применяется ко всему набору операций над сущностями, о которых DbContext знает (и их отношениям), поэтому он не применяется к сущности по сущности.

Надеемся, это поможет вам начать с того, как включить Entity Framework и работать с его одноразовым характером. DbContexts разработаны, чтобы быть относительно недолговечными, построенными и расположенными по мере необходимости. Обычно они рассчитаны на то, чтобы жить столько, сколько единица работы, веб-запрос / действие или подобное. Долгоживущие DbContexts приведут к проблемам производительности / ресурсов из-за их природы отслеживания и кэширования. (Плюс проблемы при попытке охвата вызовов SaveChanges, отмене изменений и т. Д.)

...