当使用“两级”时,上下文被处置。上下文的
执行时:
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 中得到异常陈述。
我按照此处描述的方式使用实体框架。
这种情况的常见解决方案是什么?
When doing:
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();
}
I get the exception:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
The reason I get this exception is that m_User.UserCompany is implemented like:
public _Company UserCompany
{
get
{
using (IUnitOfWork uow = UnitOfWork.Current)
{
CompanyRepository rep = new CompanyRepository();
m_Company = rep.Get(companyId.Value);
}
return m_Company;
}
}
So actually inside the first using statement I create another using statement which dispose my context when done and I get the exception in the outer using statement.
I am using the entity framework the way described here.
What is the common solution for such case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简单的解决方案是从“UserCompany”属性中删除 using 语句。这将确保 UnitOfWork.Current 不会被过早处置。
另一个想法是将属性重构为采用 IUnitOfWork 作为参数的函数。例如
,这允许您在函数范围之外管理 IUnitOfWork 的生命周期。例如,
这还有一个额外的好处,即允许 GetUserCompany() 的外部调用者始终能够管理 IUnitOfWork 的生命周期,无论它在 GetUserCompany 函数中如何使用。
The simple solution would be to remove the using statement from the 'UserCompany' property. This would ensure that the UnitOfWork.Current isnt being disposed of prematurely.
Another idea would be to re-factor the property to a function that takes a IUnitOfWork as a parameter. e.g.
this then allows you to manage the life of the IUnitOfWork outside the scope of the function. e.g.
This has the added benefit of allowing an external caller to the GetUserCompany() to always be able to manage the lifespan of the IUnitOfWork regardless of how its used within the GetUserCompany function.
我想知道如果您的
User
实体直接访问工作单元,为什么还要为存储库烦恼呢?你的架构看起来非常不一致。创建实例化和处理工作单元的中心位置 - 对于 Web 应用程序,调用这些方法的理想位置是开始和结束请求。从存储库访问工作单元(或将工作单元作为参数传递给其构造函数)并处理存储库中保留的所有数据检索和数据。不要让您的实体依赖于工作单元 - 这会使您的存储库变得多余,并且您可以回退到活动记录模式。这一切都会导致工作单元和存储库的每个 HTTP 请求生命周期的依赖注入。
诸如“工作量很大”或“我有很多地方需要改变”之类的抱怨并不是借口。你有问题,你必须解决它。解决方案需要大量重构,因为您最初的解决方案是错误的 - 我很遗憾地说您做错了,现在您必须投入时间来修复它。
I wonder why do you even bother with repositories if your
User
entity access unit of work directly? Your architecture looks very inconsistent. Create central place where unit of work is instanciated and disposed - in case of web application ideal place to call these methods is beginning and ending request. Access unit of work from repositories (or pass unit of work as parameter to their constructors) and handle all data retrieving and data persisting in repositories. Don't make your entities dependent on unit of work - that makes your repositories redundant and you can fallback to active record pattern.This all leads to dependency injection with per HTTP request lifetime for unit of work and repositories.
Complains like "it is lot of work" or "I have a lot of places to change" are not excuse. You have a problem and you have to solve it. Solution requires big amount of refactoring because your initial solution was wrong - I sad to say you did it wrong and now you must invest your time to fix it.