【发布时间】:2015-03-11 10:43:55
【问题描述】:
我有一个 Web 应用程序,我刚刚开始使用实体框架。我阅读了初学者教程,以及有关 Web 应用程序每个请求的对象上下文的好处的主题。 但是,我不确定我的上下文是否在正确的位置...
我发现这篇非常有用的帖子 (Entity Framework Object Context per request in ASP.NET?) 并使用了建议的代码:
public static class DbContextManager
{
public static MyEntities Current
{
get
{
var key = "MyDb_" + HttpContext.Current.GetHashCode().ToString("x")
+ Thread.CurrentContext.ContextID.ToString();
var context = HttpContext.Current.Items[key] as MyEntities;
if (context == null)
{
context = new MyEntities();
HttpContext.Current.Items[key] = context;
}
return context;
}
}
}
在 Global.asax 中:
protected virtual void Application_EndRequest()
{
var key = "MyDb_" + HttpContext.Current.GetHashCode().ToString("x")
+ Thread.CurrentContext.ContextID.ToString();
var context = HttpContext.Current.Items[key] as MyEntities;
if (context != null)
{
context.Dispose();
}
}
然后,我在我的页面中使用它:
public partial class Login : System.Web.UI.Page
{
private MyEntities context;
private User user;
protected void Page_Load(object sender, EventArgs e)
{
context = DbContextManager.Current;
if (Membership.GetUser() != null)
{
Guid guid = (Guid)Membership.GetUser().ProviderUserKey;
user = context.Users.Single(u => (u.Id == guid));
}
}
protected void _Button_Click(object sender, EventArgs e)
{
Item item = context.Items.Single(i => i.UserId == user.Id);
item.SomeFunctionThatUpdatesProperties();
context.SaveChanges();
}
}
我确实读了很多书,但这对我来说仍然有点困惑。 Page_Load 中的上下文获取器可以吗?我还需要使用“使用”还是使用 Global.asax 方法可以处理?
如果我对某些事情感到困惑,我很抱歉,如果有人能帮助我理解它应该在哪里,我会非常非常感激。
非常感谢!
根据 nativehr 回答和 cmets 进行编辑:
这里是 DbContextManager:
public static class DbContextManager
{
public static MyEntities Current
{
get
{
var key = "MyDb_" + typeof(MyEntities).ToString();
var context = HttpContext.Current.Items[key] as MyEntities;
if (context == null)
{
context = new MyEntities();
HttpContext.Current.Items[key] = context;
}
return context;
}
}
}
页面:
public partial class Login : System.Web.UI.Page
{
private User user;
protected void Page_Load(object sender, EventArgs e)
{
if (Membership.GetUser() != null)
{
Guid guid = (Guid)Membership.GetUser().ProviderUserKey;
user = UserService.Get(guid);
}
}
protected void _Button_Click(object sender, EventArgs e)
{
if (user != null)
{
Item item = ItemService.GetByUser(user.Id)
item.SomeFunctionThatUpdatesProperties();
ItemService.Save(item);
}
}
}
还有 ItemService 类:
public static class ItemService
{
public static Item GetByUser(Guid userId)
{
using (MyEntities context = DbContextManager.Current)
{
return context.Items.Single(i => (i.UserId == userId));
}
}
public static void Save(Item item)
{
using (MyEntities context = DbContextManager.Current)
{
context.SaveChanges();
}
}
}
【问题讨论】:
-
我不太喜欢为所有请求保留上下文(特别是如果您的网站流量非常大),但是是的,它可以工作,您不需要使用 using 和/或 dispose上下文在 Application_EndRequest 以外的任何其他地方(正如你正在做的那样),那么你的代码就很好了。
-
如果通过上下文公开的数据以只读方式使用,则考虑全局上下文实例是合适的。任何其他必须将用户数据写入数据库的场景都需要隔离每个请求的上下文实例,否则同一实例跟踪的其他用户数据也将被持久化。
标签: c# asp.net entity-framework objectcontext