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,因此无法完成操作。
如何解决此错误。
答案 0 :(得分:0)
好吧,首先,继续阅读/学习IDisposable
,using()
块以及命名约定。通过让您的代码更难于理解来记住“ a”,“ c”等,只是节省了几秒钟键入有意义的名称,您并没有得到帮助。
我很惊讶您粘贴的代码可以编译,但是却不知道什么是“上下文”与“ DbContext”(命名空间,静态类?)...
您将拥有一个扩展EF的DbContext的类,我将其称为“ MyContext”。即。
public class MyContext : DbContext
{
}
在此类内,您将声明DbSet,并且可能会使用覆盖方法OnModelCreating()
来处理实体的任何不重要的配置。
public class MyContext : DbContext
{
public DbSet<TableStudent> Students{ get; set; }
}
该类绝对不能标记为“静态”。
然后,使用您的代码来操纵学生,相关实体和/或在DbContext中具有DbSet的其他实体,您将需要确定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.
在using块的范围内做您需要做的事情。如果您需要将学生数据传递到外部(例如,从方法调用返回),请将值复制到普通的'ol C#对象(ViewModel或DTO),然后将其返回。在DbContext范围之外访问实体将导致错误,因为已经放置了学生所在的上下文。即使在作用域保持活动的情况下(例如使用静态上下文[bad!]或使用IoC容器将上下文范围限定到Web请求),也可以避免错误,但是由于延迟加载而带来意外的性能问题。>
SaveChanges
通常只需要在DbContext的生存期范围内被调用一次。当设置为了解实体之间的关系时,EF将管理实体之间的关联,例如外键,甚至是您创建的新实体。人们遇到的一个常见的恐慌点是鸡与蛋的情况,我想创建一个带有孩子的实体,但是孩子需要父ID,直到调用SaveChanges时,父ID才存在。只要父子关系正确映射,只要将子级添加到父级的子级集合中,EF将在调用SaveChanges时自动解决此问题。 SaveChanges适用于针对DbContext知道的实体(及其关系)的整套操作,因此不适用于逐个实体的情况。
希望这应该使您开始了解如何合并实体框架以及如何使用它的可处理性。 DbContext被设计为根据需要相对较短的寿命,构造和处置。通常,这些内容的作用范围是只要一个工作单元(Web请求/操作或类似的对象)可以生存。寿命较长的DbContext由于其跟踪和缓存性质而导致性能/资源问题。 (在尝试对SaveChanges调用进行范围划分,放弃更改等时,还会出现问题)