2009-02-12 55 views
9

的想法是创建一个公开的上下文句柄,但它在Web应用程序的存储类。实体框架:Singletonish ObjectContext - 好,坏,还是过度?

目前,这是我所:

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),并在请求结束时拆除。

如果这是一个单元测试的情况是对上首先需要创建,并在TestCleanup删除(在此岗位作为重要的,但只是想澄清_context对象)。

现在这背后的想法是,至少可以不必这样做:

using(TISQLEntities context = new TISQLEntities()) 
{ 
    .... 
} 

每次我想查询。我知道这可能是我的懒惰,但我只是觉得它更容易和更清洁的有:

EntityContext.Context.User.Select(...) 

和“使用”,我尽量避免在大多数情况下可避免。最重要的是,我没有为每个回发创建9001个上下文。

现在我很好奇的是,我会在想这是什么?我应该不断为每种需要的方法创建一个上下文吗?说上一回后我必须:

  • 从ID
  • 获取用户从一个id
  • 得到一个站点的站点添加到用户(user.Site = foundSite)
  • 保存用户

这可能意味着至少3个上下文。实体框架是否足够聪明,可以随时保持创建上下文?

回答

7

要实现每个请求的模式NHibernate的会议相当于是在NHibernate的一个较好的结构。虽然我不能肯定地说100%适用于EF,但它很可能是。其他会话管理模式的进一步扩大是每个商务会话的会话,让NHibernate的延长断开并重新连接会话,而不是破坏和创造缓缴一个HttpSession的持续时间的会话。如果EF允许类似的功能,而不是保持静态的开放连接,你可以看看我是如何通过我的配置文件在我的博客上使用AOP实现该模式的。

+0

我不知道这完全是一种模式,但是我之前和nHibernate一起工作过,并试图对EF做同样的事情。这基本上是我想要完成的。 – 2009-02-12 19:07:27

1

如果你想实现像NHibernate的与它的会话时,我认为这是一个好主意,有这种模式。我确信在LinqToSql中,上下文对象的实现更像是一个入口点类,它充当了一个门面。我想认为LinqToEntities是相似的。你可以有一个工厂实现来获得一个datacontext到你的模型,你可以重新使用datacontext。如果你去单身人士的方式考虑单身人士对象的瓶颈,可用性和责任。

4

检查出this blog entry,它提供了关于为实体框架上下文创建单例的更多详细信息,以及为什么在ASP.NET中不起作用,并提出了一个类似于您的建议的解决方案。