C# ObjectContext实例已被释放,不能再用于需要连接的操作。在参考表中
我有两个表客户和国家和使用(实体框架与vs 2012) 还有模型课C# ObjectContext实例已被释放,不能再用于需要连接的操作。在参考表中,c#,asp.net,sql,entity-framework,asp.net-mvc-4,C#,Asp.net,Sql,Entity Framework,Asp.net Mvc 4,我有两个表客户和国家和使用(实体框架与vs 2012) 还有模型课 using System; using System.Collections.Generic; public partial class Customer { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public
using System;
using System.Collections.Generic;
public partial class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public Nullable<int> CountrryId { get; set; }
public string Note { get; set; }
public virtual Country Country { get; set; }
}
使用系统;
使用System.Collections.Generic;
公共部分类客户
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串地址{get;set;}
公共字符串电子邮件{get;set;}
公用字符串电话{get;set;}
公共可空CountrryId{get;set;}
公共字符串注释{get;set;}
公共虚拟国家{get;set;}
}
我尝试构建一个select查询,以获取具有国家/地区名称的所有客户。但我总是收到以下错误消息
在数据上下文被释放后,您正试图访问关联属性
国家/地区
。实体框架,默认情况下。换句话说,当您第一次尝试访问关联属性时,它会再次访问数据库。要访问数据库,实体框架必须使用数据上下文。在您的情况下,它将尝试使用由jQGridDemoEntities db=new jQGridDemoEntities()
创建的数据上下文,不幸的是,该上下文已在您的代码中处理完毕。数据上下文已被释放,因为您已退出
您有三种解决此问题的方法:
- 在数据上下文仍处于活动状态时访问关联属性。更具体地说,将访问关联属性的代码移动到using块中
- 急切地加载我指定的第一个链接中解释的关联属性
customers=db.customers.Include(c=>c.Country.ToList()
- 在数据上下文仍处于活动状态时,显式选择要从数据库返回的内容。并使用这些信息构造返回的json对象
customers = db.Customers.Select(c => new { c.Id, c.FirstName, c.LastName, c.Address, c.Email, c.Phone, CountryName = c.Country.Name, c.Note };
- 您可以通过
使用块来处理数据库
使用
block not outside将代码放入
当使用使用块元素时,在使用(var元素)
中,当使用块结束时,将释放该块元素您启用了延迟加载。所以,当您尝试加载引用属性时,并没有办法这样做,因为ObjectContext是在使用
块之后处理的
有两种方法可以解决此问题:
//1. Tell EF to load Country property immediately.
using(var db = new jQGridEntities())
{
customers = db.Customers.Include(c => c.Country).ToList();
}
//2. Put return inside using block.
using(var db = new jQGridEntities())
{
customers = db.Customers.ToList();
return Json(/*your code*/);
}
您也可以禁用延迟加载,但在这种情况下,您将获得NullReferenceException
,也可以使用修复此问题。包括(c=>c.Country)
还有一个解决方案,使用ViewBag
using(var db = new jQGridEntities())
{
var customers = db.Customers.Where(c=>c.Country!=null).ToList();
ViewBag.customerlist= customers;
}
返回后尝试使用
关闭,延迟加载
可能对您的上下文启用,这意味着当您第一次尝试通过访问父上下文的属性读取其值时,将使用父上下文的连接从数据库加载国家/地区。@Mathew yes,其他部分已经是值了,因为ToList
在那里,但是Country
不是(即使在模型中,它是virtual
getter去db的地方),谢谢FlyingFox编辑我的代码。这是我的第一篇帖子。否决选民,否决第一张海报上的错误答案是不礼貌的。对于这个问题,还有其他答案不仅是错误的,而且也是危险的well@PanagiotisKanavos虽然我不太喜欢否决票(当然也不赞成在-1或-2以下否决票),但我不同意第一次否决海报是不礼貌的。不管是谁发布的,一个糟糕的答案也同样糟糕。给人们一些折扣,因为这是他们的第一次尝试,这意味着如果人们是新来的,我们更喜欢糟糕的材料。我建议,当涉及到第一次的时候,我们应该花更多的时间来解释为什么答案不好(就像你一样)。@PanagiotisKanavos澄清——我认为我们不应该对海报的信用/历史进行严重的否决。然而,我知道,当一个新来者加入并投入2美分时,一些用户会感到沮丧,他们认真地认为这会让他们和精明的程序员结对。那是自大,应该受到严厉的惩罚,用棍子殴打。打个比方说。@KonradViltersten记得最基本的指令——“友善”。否则,第一次发布的海报将成为最后一次发布。延迟加载问题无法通过留下孤立的上下文来解决。事实上,它甚至不能解决这个问题,因为垃圾收集器可以在加载国家/地区属性之前随时处理上下文。因此,请确保您使用的是System.Data.Entity,否则VS会在第二个选项中抱怨lambda表达式。如果Include
没有帮助,我还可以尝试什么?