绑定时已释放ObjectContext实例

.net c# entity-framework exception-handling

这是我的代码:

public class JobsRepository:BaseNewsletterRepository
{
   public IEnumerable<Job> GetJobs()
   {
        var jobs = Newsletterctx.Jobs.Include("Info").OrderBy(o => o.JobID);             
        return jobs.AsEnumerable();
   }
}

public class BusinessNewsletter
{
   public static IEnumerable<Job> GetJobs()
   {      
        using (JobsRepository jobsRepository = new JobsRepository())
        {
            return  jobsRepository.GetJobs();
        }    
    }
}    

rptJobs.DataSource = BusinessNewsletter.GetJobs();
rptJobs.DataBind();

当我尝试绑定时,我得到错误:

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

是唯一的解决方案,在BusinessNewsletter类中转换和返回List吗?

public static IList<Job> GetJobs()
{
    IList<Job> job;
    using (JobsRepository jobsRepository = new JobsRepository())
    {
        job = jobsRepository.GetJobs().ToList();
    }
    return job;
}

另一个相关问题:

如何在不指定特定类型( List<type>IEnumerable<type> )的情况下检索数据并将数据绑定到转发器
如果我返回这样的特定对象,我需要它:

var specificJob = from job in Newsletterctx.Jobs.Include("Info")
                  select new
                  {
                      ID = job.JobID,
                      EmailId = job.Info.PreparedEmailID
                  };

我必须为该对象创建特定的类?

一般承认的答案

默认情况下,Entity Framework对导航属性使用延迟加载。这就是为什么这些属性应该标记为虚拟的原因 - EF为您的实体创建代理类并覆盖导航属性以允许延迟加载。例如,如果你有这个实体:

public class MemberLoan
{
   public string LoandProviderCode { get; set; }
   public virtual Membership Membership { get; set; }
}

实体框架将返回从此实体继承的代理,并向此代理提供DbContext实例,以便稍后允许延迟加载成员资格:

public class MemberLoanProxy : MemberLoan
{
    private CosisEntities db;
    private int membershipId;
    private Membership membership;

    public override Membership Membership 
    { 
       get 
       {
          if (membership == null)
              membership = db.Memberships.Find(membershipId);
          return membership;
       }
       set { membership = value; }
    }
}

因此,实体具有用于加载实体的DbContext实例。那是你的问题。你有using CosisEntities using块。在返回实体之前处理上下文。当某些代码稍后尝试使用延迟加载的导航属性时,它会失败,因为在那一刻处置了上下文。

要修复此行为,您可以使用以后需要的急切加载导航属性:

IQueryable<MemberLoan> query = db.MemberLoans.Include(m => m.Membership);

这将预加载所有成员资格,并且不会使用延迟加载。有关详细信息,请参阅MSDN上的加载相关实体文章。


热门答案

CosisEntities类是您的DbContext 。在using块中创建上下文时,您将为面向数据的操作定义边界。

在您的代码中,您尝试从方法中发出查询结果,然后在方法中结束上下文。传递结果的操作然后尝试访问实体以填充网格视图。在绑定到网格的过程中的某个地方,正在访问延迟加载的属性,并且Entity Framework正在尝试执行查找以获取值。它失败了,因为相关的上下文已经结束。

你有两个问题:

  1. 绑定到网格时,您将加载延迟实体。这意味着您正在对SQL Server执行大量单独的查询操作,这会降低所有内容的速度。您可以通过在默认情况下急切加载相关属性,或者要求Entity Framework使用Include扩展方法将它们包含在此查询的结果中来解决此问题。

  2. 您过早地结束了上下文: DbContext应该在整个正在执行的工作单元中可用,只有在您完成手头的工作时才会将其处理DbContext 。对于ASP.NET,工作单元通常是正在处理的HTTP请求。




许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因