EntityFramework 4.5 -即使在使用Include之后仍然得到ObjectDisposedExcepti

本文关键字:之后 ObjectDisposedExcepti Include EntityFramework | 更新日期: 2023-09-27 18:10:39

我正面临异常 ObjectContext实例已被处置,不能再用于需要连接的操作,即使在使用Include方法之后。

检索实体的函数:

    public List<Entity.CapacityGrid> SelectByFormula(string strFormula, int iVersionId)
    {
        // declaration
        List<Entity.CapacityGrid> oList;
        // retrieve ingredients
        oList = (from Grid in _Dc.CapacityGrid.Include("EquipmentSection")
                             join Header in _Dc.CapacityHeader
                             on Grid.HeaderId equals Header.HeaderId
                             where Header.Formula == strFormula
                             && Header.VersionId == iVersionId
                             select Grid).ToList();
        // return
        return oList;
下面是函数的用法:
        // retrieve ingredient quantity by equipement
        using (Model.CapacityGrid oModel = new Model.CapacityGrid(Configuration.RemoteDatabase))
            oQuantity = oModel.SelectByFormula(strFormulaName, iVersionId);
        // code to throw the exception
        var o = (oQuantity[0].EquipmentSection.TypeId);

我明白使用正在关闭连接。我认为ToList()将在关闭之前实例化包含中的对象列表和相关对象。

谁能指出我做错了什么吗?对不起,我的问题不清楚。我确实理解,包括在using的括号内抛出异常的行是有效的,但我不明白为什么包含不工作?

谢谢!

EntityFramework 4.5 -即使在使用Include之后仍然得到ObjectDisposedExcepti

尝试更改

    // retrieve ingredient quantity by equipement
    using (Model.CapacityGrid oModel = new Model.CapacityGrid(Configuration.RemoteDatabase))
   {  // <-- **add these**
        oQuantity = oModel.SelectByFormula(strFormulaName, iVersionId);
    // code to throw the exception
    var o = (oQuantity[0].EquipmentSection.TypeId);
   } // <-- **add these**

裁判:http://msdn.microsoft.com/en-us/library/yh598w02.aspx

如果没有{}包含使用,则在第一行之后立即处理连接。因为实体框架使用表达式树(这意味着请求在真正需要之前不会执行),所以您的查询发生在var o = (oQuantity[0].EquipmentSection.TypeId);

你的问题有三个解决方案。这些都来自这里的链接,是链接到相关实体的三种方式。第一个解决方案是您一直在使用的延迟加载解决方案。只要修改你的代码,它将工作。它抛出异常的原因是因为延迟加载只在需要时发生。当您只需要在几个实体上加载相关实体时,这是一个很好的解决方案。

// retrieve ingredient quantity by equipement
using (Model.CapacityGrid oModel = new Model.CapacityGrid(Configuration.RemoteDatabase))
{
    oQuantity = oModel.SelectByFormula(strFormulaName, iVersionId);
    // Lazy-load occurs here, so it needs to have access to the
    // context, hence why it is in the using statement.
    var o = (oQuantity.First().EquipmentSection.TypeId);
}

第二个解决方案是使用急切加载(如@DavidG所建议的)。因为您只加载找到的第一个实体的相关实体,所以我不建议您在您的情况下使用它,因为它将加载所有oQuantity实体的EquipmentSection实体。在你的SelectByFormula方法中,使用一个Include语句,如相关链接所示,它将在第一次调用时加载它(它不会复制对数据库的访问,但它会一次拉出更多的数据)。

第三个解决方案是避免依赖于延迟加载,并且可以是一个很好的方法。这是显式加载技术,它要求您指定要在指定的实体上加载EquipmentSection相关实体。

我希望这些解释对你有帮助。

同样,你可能想要考虑在你的SelectByFormula方法上返回一个IQueryable。这样,如果您必须过滤请求,就像使用First()方法只获取第一次出现的请求一样,您就不会仅为一个实例提取所有内容。