Entity Framework - Load Reference Keys after disposing entity object context
I am using ASP.Net / WebForms / Entity Model / Framework 3.5
Here is my project's simple structure Forms > BLL > DAL ( uses entity model )
Here is my DAL's snippet
public class MyDAL : IDisposable
{
private MyEntities db;
public BaseDAL()
{
db = new MyEntities();
}
public User GetUserByID(int userId)
{
try
{
IQueryable<User> objUser = null;
objUser = from res in db.Users
where res.UserId == userId
select res;
return objUser.FirstOrDefault();
}
开发者_运维技巧catch
{
throw;
}
}
public void Dispose()
{
db.Dispose();
}
}
I call the DAL's function from my BLL like this
public class MyBLL
{
public User GetUserByID(int userId)
{
try
{
using (MyDAL objMyDAL = new MyDAL())
{
return objMyDAL.GetUserByID(userId);
}
}
catch
{
throw;
}
}
}
I am calling the DAL through using block so MyDAL's Dispose event will fire soon after the BLL returns the User object. So at this point ObjectContext instance gets disposed.
Now in my Web Form, I am calling this function like this to get user information and Group details which is a foreign key of user_Group Table in User table
protected void Page_Load(object sender, EventArgs e)
{
MyBLL objMyBll = new MyBLL();
User objUser = objMyBll.GetUserByID(123);
objUser.User_GroupReference.Load(); // ERROR LINE
int groupId = objUser.User_Group.Group_Id;
}
When the ode comes on line objUser.User_GroupReference.Load();
I get this exception
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
How to resolve this? If I do not do db.Dispose();
in my DAL's dispose method, it works fine and no exceptions comes. But if I do not dispose the db object there, when & where should I dispose it?
And how to access Reference Keys after disposed object context?
The exception is fired because lazy loading is fired when you access that navigation property but lazy loading works only within scope of context used to load the entity. If you dispose the context you will lose lazy loading ability. There is no way to use lazy loading after context disposal (except attaching the entity to the new context but it will only work if you detach it from the original context before you dispose it).
In your architecture you must use Include
to explicitly load every relation you will need in upper layers. If you want to use lazy loading your context must live for the whole duration of the request. In case of web forms it can be handled for example in BeginRequest
and EndRequest
event handlers where you create context in BeginRequest
and dispose it in EndRequest
. The context will be stored in HttpContext.Items
. You should get the context from this collection (you can make helper method for that) and pass it to constructor of BLL which will in turn pass it to DAL. Don't access HttpContext.Items
from BLL or DAL.
精彩评论