ObjectContext实例已被释放,不能再用于需要连接的操作。 在参考表中
我有两个表Customers和Country and use(Entity Framework with 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 string Address { get; set; } public string Email { get; set; } public string Phone { get; set; } public Nullable CountrryId { get; set; } public string Note { get; set; } public virtual Country Country { get; set; } }
我尝试构建一个选择查询,以获取具有国家/地区名称的所有客户。 但我总是得到以下错误消息。
您正在尝试在处置数据上下文后访问关联属性Country
。 默认情况下,entity framework会懒惰地加载关联属性 。 换句话说,当您第一次尝试访问关联属性时,它会再次访问数据库。 为了实现数据库之旅,Entity Framework必须使用数据上下文。 在您的情况下,它将尝试使用由jQGridDemoEntities db = new jQGridDemoEntities()
创建的数据上下文,遗憾的是,这些数据上下文已放置在您的代码中。 数据上下文已被释放,因为您已退出使用块 。
您有三种方法可以解决此问题:
-
在数据上下文仍处于活动状态时访问关联属性。 更具体地说,将访问关联属性的代码移动到使用块中
-
急切加载关联属性,如我指定的第一个链接中所述
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 };
您启用了延迟加载。 因此,当您尝试加载引用属性时,无法执行此操作,因为ObjectContext在using
块之后立即处理。
有两种方法可以解决它:
//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
,也可以使用.Include(c => c.Country)
。
您using
块处理数据库
将代码放入using
块而不是外部。
当使用块元素时,在使用块结束时使用using(var element)
还有一个解决方案,使用ViewBag
using(var db = new jQGridEntities()) { var customers = db.Customers.Where(c=>c.Country!=null).ToList(); ViewBag.customerlist= customers; }