ObjectContext 实例已被处置,不能再使用
The ObjectContext instance has been disposed and can no longer be used
我已经看到这个问题被问了一百万次,但我遇到的每一个建议似乎都已经涵盖了。
我的 MVC 解决方案中有 entity framework,我有一个 'repository' 试图检索 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 实例已被释放,不能再用于需要连接的操作。
我不知道在哪里打开这个,我很欣赏 entity framework 'lazy-loads' 关系数据集,如果需要的话,我很欣赏尝试序列化整个集合确实尝试加载这些(在 using 语句之外),但我在那里有 'Include'。
我试过的
我试过 'include',我也确保没有其他关联是 MyObject
class 的一部分(即我没有其他 Include()
s写)。
当您使用 Include 和 Lazy loading,并将 dbContext 包装在 Using 语句中时,一旦它尝试获取链接的对象,dbContext 就已经被释放了。
您可以像这样尝试预先加载导航 属性:
IQueryable<MyObjects> query = db.MyObjects.Include(m => m.Contact);
或者您可以删除 Using 语句,因为它限制了您的延迟加载...
为避免这种情况,您需要 options.Don 不将您的导航属性声明为 virtual
或在您的上下文中禁用 延迟加载 行为。默认情况下启用延迟加载,它是通过创建派生代理类型的实例然后覆盖 virtual
属性以添加加载挂钩来实现的。所以,如果你想使用序列化程序,我建议你关闭延迟加载:
public class YourContext : DbContext
{
public YourContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
这些 link 可以帮助您更好地理解我在回答中解释的内容:
如果从导航属性中删除 virtual
关键字,POCO 实体将不满足第二个 link 中描述的要求,因此,EF 不会创建代理 class 延迟加载您的导航属性。但是如果你禁用延迟加载,即使你的导航属性是 virtual
,它们也不会被加载到任何实体中。使用序列化器时禁用延迟加载是个好主意。大多数序列化程序通过访问类型实例上的每个 属性 来工作。
作为第三个选项,您可以在您不想作为实体的一部分序列化的导航属性上使用 JsonIgnore 属性,但正如我之前所说,最好的选择是禁用惰性加载中。
我遇到了同样的问题,解决方法如下;
我创建了一个新对象并放入了我从数据库中获取对象后要使用的值。
示例代码:
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);
}
我已经看到这个问题被问了一百万次,但我遇到的每一个建议似乎都已经涵盖了。
我的 MVC 解决方案中有 entity framework,我有一个 'repository' 试图检索 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 实例已被释放,不能再用于需要连接的操作。
我不知道在哪里打开这个,我很欣赏 entity framework 'lazy-loads' 关系数据集,如果需要的话,我很欣赏尝试序列化整个集合确实尝试加载这些(在 using 语句之外),但我在那里有 'Include'。
我试过的
我试过 'include',我也确保没有其他关联是 MyObject
class 的一部分(即我没有其他 Include()
s写)。
当您使用 Include 和 Lazy loading,并将 dbContext 包装在 Using 语句中时,一旦它尝试获取链接的对象,dbContext 就已经被释放了。 您可以像这样尝试预先加载导航 属性:
IQueryable<MyObjects> query = db.MyObjects.Include(m => m.Contact);
或者您可以删除 Using 语句,因为它限制了您的延迟加载...
为避免这种情况,您需要 options.Don 不将您的导航属性声明为 virtual
或在您的上下文中禁用 延迟加载 行为。默认情况下启用延迟加载,它是通过创建派生代理类型的实例然后覆盖 virtual
属性以添加加载挂钩来实现的。所以,如果你想使用序列化程序,我建议你关闭延迟加载:
public class YourContext : DbContext
{
public YourContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
这些 link 可以帮助您更好地理解我在回答中解释的内容:
如果从导航属性中删除 virtual
关键字,POCO 实体将不满足第二个 link 中描述的要求,因此,EF 不会创建代理 class 延迟加载您的导航属性。但是如果你禁用延迟加载,即使你的导航属性是 virtual
,它们也不会被加载到任何实体中。使用序列化器时禁用延迟加载是个好主意。大多数序列化程序通过访问类型实例上的每个 属性 来工作。
作为第三个选项,您可以在您不想作为实体的一部分序列化的导航属性上使用 JsonIgnore 属性,但正如我之前所说,最好的选择是禁用惰性加载中。
我遇到了同样的问题,解决方法如下;
我创建了一个新对象并放入了我从数据库中获取对象后要使用的值。
示例代码:
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);
}