ObjectContext实例已被处理,不能再使用

本文关键字:不能 处理 实例 ObjectContext | 更新日期: 2023-09-27 17:54:39

这个问题我已经被问过无数次了,但是我遇到的每一个建议我似乎都已经回答过了。

我在我的MVC解决方案中有实体框架,我有一个"存储库",它试图检索MyObject s的集合:

public static List<MyObject> GetMyObjects()
{
   using (var context = new MyEntities())
   {
       return context.MyObjects.Include("Contact").OrderByDescending(o => o.Date).ToList();
   }
}

我调用这个方法作为一个控制器动作的一部分,它试图序列化它:

public JsonResult All()
{
   return Json(MyRepository.GetMyObjects(), JsonRequestBehavior.AllowGet);
}

我得到以下错误:

ObjectContext实例已被处理,不能再用于需要连接的操作。

我不知道在哪里打开这个,我欣赏实体框架'惰性加载'关系数据集,如果和当他们需要,我欣赏尝试序列化整个集合确实会尝试加载这些(使用语句之外),但我有'Include'在那里。

What I've try

我已经尝试了'包括',我也确保没有其他协会是MyObject类的一部分(即我没有其他Include() s要写)。

ObjectContext实例已被处理,不能再使用

要避免这种情况,您有一些选择。不要将导航属性声明为virtual或禁用惰性加载行为。延迟加载在默认情况下是启用的,通过创建派生代理类型的实例,然后重写virtual属性来添加加载钩子来实现。所以,如果你想使用序列化器,我建议你关闭延迟加载:

public class YourContext : DbContext 
{ 
    public YourContext() 
    { 
        this.Configuration.LazyLoadingEnabled = false; 
    } 
}

这些链接可以帮助你更好地理解我在回答中解释的内容:

  • 加载相关实体
  • 创建POCO代理的要求

如果你从导航属性中删除virtual关键字,POCO实体不满足第二个链接中描述的要求,因此,EF不会创建一个代理类来延迟加载你的导航属性。但是如果你禁用了延迟加载,即使你的导航属性是virtual,它们也不会被加载到任何实体中。在使用序列化器时禁用延迟加载是个好主意。大多数序列化器通过访问类型实例上的每个属性来工作。

作为第三个选项,你可以在你的导航属性上使用JsonIgnore属性,你不想被序列化为你的实体的一部分,但正如我之前所说,最好的选择是禁用延迟加载。

当您使用Include并使用Lazy加载时,并将dbContext包装在using语句中,那么一旦它试图获得链接对象,dbContext就已经被处置了。你可以尝试像这样快速加载导航属性:

IQueryable<MyObjects> query = db.MyObjects.Include(m => m.Contact);

或者你可以去掉Using语句,因为它限制了你的延迟加载…

我遇到了同样的问题,并像下面这样解决了;

我创建了一个新的对象,并把我要使用的值从数据库获取对象。

示例代码:

 var listFromDb= db.XTable.Where(x => x.Id > 5).ToList();
 var list = new List<Package>();
 foreach (var item in listFromDb)
 {
     var a = new Package()
     {
          AccountNo = item.AccountNo,
          CreateDate = item.CreateDate,
          IsResultCreated = item.IsResultCreated,
        };
        list.Add(a);
      }