ObjectContext实例已被释放,不能再用于需要连接的操作。 在参考表中

我有两个表CustomersCountry 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; }