我们的想法是创建一个暴露上下文但在Web应用程序中处理它的存储的类。
目前这就是我所拥有的:
public class EntityContext
{
private static String MAIN_CONTEXT_KEY = "MainContext";
private static TISQLEntities _context;
public static void RemoveContext()
{
if (
HttpContext.Current != null
&&
HttpContext.Current.Items[MAIN_CONTEXT_KEY] != null
)
{
((TISQLEntities)HttpContext.Current.Items[MAIN_CONTEXT_KEY]).Dispose();
HttpContext.Current.Items[MAIN_CONTEXT_KEY] = null;
}
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
public static TISQLEntities Context
{
get
{
if (HttpContext.Current == null)
{
if (_context == null)
{
_context = new TISQLEntities();
}
return _context;
}
if (HttpContext.Current.Items[MAIN_CONTEXT_KEY] == null)
{
HttpContext.Current.Items[MAIN_CONTEXT_KEY] = new TISQLEntities();
}
return (TISQLEntities)HttpContext.Current.Items[MAIN_CONTEXT_KEY];
}
}
}
然后在Global.asax文件中:
protected void Application_EndRequest(object sender, EventArgs e)
{
EntityContext.RemoveContext();
}
这个想法是,如果使用Web应用程序运行,则首先需要创建上下文(并保存到当前的HttpContext),并在请求结束时将其拆除。
如果这是一个UnitTest情况,则在第一次需要时创建并在TestCleanup中删除(在这篇文章中并不重要,只是想澄清_context对象)。
现在,这背后的想法至少不必这样做:
using(TISQLEntities context = new TISQLEntities())
{
....
}
每次我想查询。我意识到这可能是我的懒惰,但我只是认为它更容易和更清洁:
EntityContext.Context.User.Select(...)
避免在大多数情况下我试图避免使用“使用”。最重要的是,我不会为每个回发创建9001个上下文。
现在我很好奇的是,我在想这个吗?我应该继续为每个需要的方法创建一个上下文吗?在帖子上说我必须:
这可能需要至少3个背景。实体框架是否足够智能,可以随时继续创建上下文?
答案 0 :(得分:6)
您正在为每个请求模式实现NHibernate的会话等效,这是NHibernate中的一个很好的构造。虽然我不能说100%肯定它适用于EF它很可能是。进一步扩展其他会话管理模式的是每个业务对话的会话,它允许NHibernate通过断开和重新连接会话而不是销毁和创建来延长在HttpSession持续时间内持有会话。如果EF允许类似的能力而不是保持静态打开连接,那么您可以通过我的个人资料查看我在博客上使用AOP实现该模式的方式。
答案 1 :(得分:4)
查看this blog entry,它提供了有关为Entity Framework上下文创建单例的更多详细信息,以及为什么这在ASP.NET中不起作用,并提出了一个类似于您建议的解决方案。< / p>
答案 2 :(得分:1)
如果你试图用它的Session实现像NHibernate这样的东西,我觉得拥有这种模式是个好主意。我确信在LinqToSql中,上下文对象实现更像是一个作为外观的入口点类。我想LinqToEntities是类似的。您可以使用工厂实现来获取模型的datacontext,您可以在其中回收datacontext。如果你采用单例方式考虑单例对象的瓶颈,可用性和责任。