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

时间:2014-02-25 07:07:24

标签: c# asp.net sql entity-framework asp.net-mvc-4

我有两个表客户国家并使用(实体框架与vs 2012)

enter image description here

模型类

 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; }
 }

我尝试构建一个选择查询以获取具有国家/地区名称的所有客户。但我总是收到以下错误消息。

enter image description here

3 个答案:

答案 0 :(得分:39)

您正在尝试在处理数据上下文后访问关联属性Country。实体框架,默认情况下为loads association properties lazily。换句话说,当您第一次尝试访问关联属性时,它会再次访问数据库。要进行数据库访问,Entity Framework必须使用数据上下文。在您的情况下,它将尝试使用由jQGridDemoEntities db = new jQGridDemoEntities()创建的数据上下文,遗憾的是,这些数据上下文已在您的代码中被置于此处。数据上下文已被释放,因为您已退出using block

您有三种方法可以解决此问题:

  • 当数据上下文仍处于活动状态时访问关联属性。更具体地说,将访问关联属性的代码移动到使用块

  • 急切加载关联属性,如我指定的第一个链接

    中所述

    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
    };
    

答案 1 :(得分:8)

您启用了延迟加载。因此,当您尝试加载引用属性时,无法执行此操作,因为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)修复此问题。

答案 2 :(得分:1)

您按using阻止

处理数据库

将您的代码放入using块而不是外面。

使用using块元素时使用块结束时using(var element)处置