EntityFramework 4.5 - 即使在使用Include后仍然会获得ObjectDisposedException

Seb*_*ico 5 c# entity-framework

我正面临异常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;
Run Code Online (Sandbox Code Playgroud)

这里使用的功能:

        // 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);
Run Code Online (Sandbox Code Playgroud)

我知道使用正在关闭连接.我以为ToList()会在关闭之前实例化对象列表和include中的相关对象.

有人能指出我做错了吗?对不起,我的问题不明确.我明白包含在使用的括号内抛出异常的行正在工作,但我不明白为什么包含不起作用

谢谢!

gre*_*tro 1

您的问题有三种解决方案。这些来自此处的链接,是链接到相关实体的三种方法。第一个解决方案是您一直在使用的延迟加载解决方案。只需将您的代码修改为此即可。它抛出异常的原因是因为延迟加载仅在您需要时才会发生。当您需要仅在少数实体上加载相关实体时,这是一个很好的解决方案。

// 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);
}
Run Code Online (Sandbox Code Playgroud)

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

第三种解决方案是避免依赖Lazy Loading,也是一个不错的方法。这是显式加载技术,需要您指定要EquipmentSection在指定实体上加载相关实体。

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

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