当使用“两级”上下文时,上下文被处理

时间:2011-05-17 06:10:57

标签: c# .net entity-framework

做的时候:

    using (IUnitOfWork uow = UnitOfWork.Current)
    {
        LocationRepository rep = new LocationRepository();
        Location loc = new Location()
        {
            CompanyId = m_User.UserCompany.CompanyId,
            Name = locationName
        };
        rep.Insert(loc);
        uow.Commit();
    }

我得到例外:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

我得到此异常的原因是m_User.UserCompany实现如下:

public _Company UserCompany
{
    get
    {
                using (IUnitOfWork uow = UnitOfWork.Current)
                {
                    CompanyRepository rep = new CompanyRepository();
                    m_Company = rep.Get(companyId.Value);
                }
        return m_Company;
    }
}

所以实际上在第一个using语句中我创建了另一个using语句,它在完成后处理我的上下文,并在外部using语句中得到异常。

我按照here描述的方式使用实体框架。

这种情况的常见解决方案是什么?

2 个答案:

答案 0 :(得分:1)

简单的解决方案是从'UserCompany'属性中删除using语句。这样可以确保UnitOfWork.Current不会过早处理。

另一个想法是将属性重新分解为将IUnitOfWork作为参数的函数。 e.g。

public _Company GetUserCompany(IUnitOfWork uow)
{
    CompanyRepository rep = new CompanyRepository();
    m_Company = rep.Get(companyId.Value);              
    return m_Company;
}

然后,您可以在函数范围之外管理IUnitOfWork的生命周期。 e.g。

using (IUnitOfWork uow = UnitOfWork.Current)
{        
    /* Snip...*/

        CompanyId = m_User.GetUserCompany(uow).CompanyId,

    /* Snip...*/
}

这样做的另一个好处是允许GetUserCompany()的外部调用者始终能够管理IUnitOfWork的生命周期,无论其在GetUserCompany函数中的使用方式如何。

答案 1 :(得分:0)

我想知道如果您的User实体直接访问工作单元,为什么还要打扰存储库呢?您的架构看起来非常不一致。创建工作单元实例化和处置的中心位置 - 在Web应用程序的情况下,调用这些方法的理想位置是开始和结束请求。从存储库访问工作单元(或将工作单元作为参数传递给它们的构造函数)并处理存储库中持久存储的所有数据。不要让您的实体依赖于工作单元 - 这会使您的存储库变得多余,并且您可以回退到活动记录模式。

这一切都导致了对工作单元和存储库的每个HTTP请求生命周期的依赖注入。

抱怨像“这是很多工作”或“我有很多地方要改变”不是借口。你有一个问题,你必须解决它。解决方案需要重构的大量,因为您最初的解决方案是错误的 - 我伤心地说,你这样做是错误的,现在你必须投入自己的时间来修复它。