EntityFramework 4.5 - 即使使用Include,仍然会得到ObjectDisposedException [英] EntityFramework 4.5 - Still get ObjectDisposedException even after using Include

查看:142
本文介绍了EntityFramework 4.5 - 即使使用Include,仍然会得到ObjectDisposedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这里检索实体的功能:

  public List< Entity.CapacityGrid> SelectByFormula(string strFormula,int iVersionId)
{
//声明
列表< Entity.CapacityGrid> oList;

//检索成分
oList =(从_Dc.CapacityGrid.Include(EquipmentSection)中的网格
在_Dc.CapacityHeader中的标头
在Grid.HeaderId等于Header.HeaderId
其中Header.Formula == strFormula
&& Header.VersionId == iVersionId
select Grid).ToList();

// return
return oList;

这里使用的功能:



<$ ($)
oQuantity = oModel.SelectByFormula(strFormulaName, iVersionId);

//代码抛出异常
var o =(oQuantity [0] .EquipmentSection.TypeId);

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


有人可以指出我做错了什么吗?
抱歉,我的问题不清楚。我明白,包括在异常括号内的异常行正在运行,但是我不明白为什么include不起作用?


谢谢!

解决方案

您的问题有三种解决方案。这些来自此链接此处,并且是三种链接到相关实体第一个解决方案是您一直在使用的Lazy加载解决方案。只需修改你的代码就可以了。引发异常的原因是因为只有在需要时才会发生延迟加载。当您需要仅在几个实体上加载相关实体时,这是一个很好的解决方案。

  //通过equipement检索成分数量
使用(Model.CapacityGrid oModel = new Model.CapacityGrid(Configuration.RemoteDatabase))
{
oQuantity = oModel.SelectByFormula(strFormulaName,iVersionId);

// Lazy-load在这里,所以它需要访问
//上下文,因此为什么它在using语句中。
var o =(oQuantity.First()。EquipmentSection.TypeId);
}

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



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



我希望这些解释可以帮助您。



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


I am facing the exception The ObjectContext instance has been disposed and can no longer be used for operations that require a connection even after using the Include method.

Here the function that retrieve the entities:

    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;

Here the usage of the function:

        // 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);

I understand that the using is closing the connection. I thought the ToList() will instantiated the list of objects and the related objects in the include before closing.

Can someone point me out what I do wrong? Sorry, my question was not clear. I do understand that including the line that throw exception inside the bracket of the using is working, but I do not figure out why does the include does not works?

Thank you!

解决方案

There are three solutions to your problem. These come from this link here and are the three ways to link to a Related Entity. The first solution is the Lazy loading solution, that you have been using. Just modify your code to this and it will work. The reason why it was throwing an exception is because lazy loading occurs only when you need it. It's a great solution when you need to load the related entities only on a few entities.

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

The second solution is to use eager-loading (as suggested by @DavidG). Because you only load the related entity of the first entity found, I do not recommend you use this in your case because it will load the EquipmentSection entity of all your oQuantity entities. In your SelectByFormula method, use an Include statement as shown in the related link and it will load it on the first call (it will not duplicate the access to the database, but it will pull more data at once).

The third solution is to avoid relying on Lazy Loading, and can be a good way to go to. It's the Explicit loading technique, which will require you to specify that you want to load the EquipmentSection related entity on the specified entity.

I hope those explanations help you.

Also, you might want to consider returning an IQueryable on your SelectByFormula method. This way, if you have to filter requests, like with the First() method to obtain only the first occurance, you are not pulling everything only for one instance.

这篇关于EntityFramework 4.5 - 即使使用Include,仍然会得到ObjectDisposedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆