情况:来自过去上下文的会话中的对象不能设置为另一个对象的父对象,因为其他对象在新的上下文中。
假设我在会话中有一个用户从上下文中检索过。现在页面重新加载,该上下文已被解除,并且创建了新的上下文。
someUser = context.First(user => user.id == id);
Session["SomeUser"] = someUser
...
context.Dispose();
Page Reload
userAddress = new UserAddress();
userAddress.User = (User)Session["SomeUser"]; //BOOM NOT IN SAME CONTEXT
我想做的是:
if(!context.SomeUsers.Contains((User)Session["SomeUSer"]) //Only check context NOT DATABASE
{
//Reload from database
//Set user in session to new object
}
这个想法是,如果会话中的对象不属于当前上下文,则从数据库重新加载它,使其现在由与当前上下文中的每个其他对象相同的上下文“拥有”。 (我根据请求使用上下文)
更新
所以我暂时这样做,直到我能更好地了解如何解决这个问题:
Int32 sessionUser = sessionUser .UserID;
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
if (userCheck != sessionUser)
{
sessionUser = userCheck;
}
想法是查看会话中的对象(sessionUser)是否与上下文中的对象相同。现在if工作得很好。第一次创建上下文时,应该抓住数据库并抓住用户。一旦比较,很明显它们不一样,而sesionUser现在是上下文中的用户。下次检查if时,sessionUser和userToCheck是相同的。
问题仍然是:
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
始终点击数据库。这不是一个好的解决方案。
更新
毕竟,这可能就是答案。我忘记了这条规则:x是ObjectQuery类型的属性。 当你执行ObjectQuery时,它 将永远打到后盾商店。 这就是他们所做的。如果你不想要 然后执行数据库查询 不要使用ObjectQuery。
答案 0 :(得分:2)
好的。
ChatUser userCheck = (ChatUser)EntityContext.Context.GetObjectByKey(returnValue.EntityKey);
if(userCheck != returnValue)
{
sessionUser = userCheck;
}
GetObjectByKey方法,描述为:
GetObjectByKey尝试检索 具有指定的对象 来自ObjectStateManager的EntityKey。 如果当前未加载该对象 进入对象上下文,查询是 执行以试图返回 来自数据源的对象。
做了一些测试并且它做了它说的。第一次通过(上下文是根据请求创建的)它命中数据库并根据会话中的内容检查该对象。两者不一样,因此它将sessionUser设置为新对象,因此现在在上下文和会话中具有sessionUser。下次围绕GetObjectByKey方法只检查上下文(As Profiler显示没有数据库交互)。耶。
答案 1 :(得分:0)
为什么不检查用户ID?
context.Users.Any(user => user.Id = ((User)session["SomeUser"]).Id)
或者您可以从旧上下文中分离用户对象,并使用Context.Attach()将其附加到新上下文。