context is disposed when using "two levels" of context
When doing:
using (IUnitOfWork uow = UnitOfWork.Current)
{
LocationRepository rep = new Location开发者_StackOverflowRepository();
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?
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.
public _Company GetUserCompany(IUnitOfWork uow)
{
CompanyRepository rep = new CompanyRepository();
m_Company = rep.Get(companyId.Value);
return m_Company;
}
this then allows you to manage the life of the IUnitOfWork outside the scope of the function. e.g.
using (IUnitOfWork uow = UnitOfWork.Current)
{
/* Snip...*/
CompanyId = m_User.GetUserCompany(uow).CompanyId,
/* Snip...*/
}
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.
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.
精彩评论