2009-02-12 17 views
9

La idea es crear una clase que expone un contexto pero maneja el almacenamiento de la misma en una aplicación web.Entity Framework: SingleConnect ObjectContext: bueno, malo o pensamiento oculto?

Actualmente esto es lo que tengo:

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]; 
     } 
    } 
} 

Y luego en el archivo Global.asax:

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    EntityContext.RemoveContext(); 
} 

La idea es que si se ejecuta con una aplicación web, el contexto se crea en la primera necesidad (y se guarda en el HttpContext actual) y se destruye cada vez que se completa la solicitud.

Si esta es una situación UnitTest es contra creada en la primera necesidad y eliminada en TestCleanup (No es tan importante en esta publicación, pero solo quería aclarar el objeto _context).

Ahora la idea detrás de esto es en lo más mínimo para no tener que hacer esto:

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

Cada vez que desea consultar. Me doy cuenta de esto puede ser que yo sea perezoso, pero solo creo que es más fácil y más limpio que tener:

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

y evita el "uso" que trato de evitar la mayoría de casos. Además de eso, no estoy creando contextos 9001 por devolución de datos.

Ahora, lo que me produce curiosidad es que estoy demasiado pensando en esto? ¿Debo seguir creando un contexto para cada método que lo necesite? Decir en un puesto de vuelta tengo que:

  • conseguir que el usuario de un identificador de
  • Obtener un sitio desde un id
  • Añadir el Sitio al Usuario (user.Site = foundSite)
  • Guardar el usuario

Eso podría implicar al menos 3 contextos. ¿El marco de la entidad es lo suficientemente inteligente como para mantener la creación de contextos siempre?

Respuesta

7

Está implementando el equivalente de la sesión de NHibernate por patrón de solicitud, que es una buena construcción en NHibernate. Si bien no puedo decir con certeza al 100% que sea aplicable a EF, lo más probable es que sea así. Una mayor expansión en otros patrones de administración de sesiones es la Sesión por Conversación Empresarial que permite a NHibernate extender la celebración de una sesión durante la duración de una HttpSesión desconectando y reconectando la sesión en lugar de destruirla y crearla. Si el EF permite una habilidad similar en lugar de mantener una conexión estática abierta, podrías ver cómo implementé ese patrón usando AOP en mi blog a través de mi perfil.

+0

No sabía que esto era un patrón exactamente, pero sí que han trabajado con NHibernate antes y estaba tratando de hacer lo mismo con EF. Eso es básicamente lo que estoy tratando de lograr. –

+0

Sí, hay algunos patrones de gestión de sesión. El patrón correcto más común es sesión por solicitud, sesión por conversación de negocios es muy nuevo, los antipatrones para administración de sesión son sesión por aplicación y sesión por llamada (sin administración, crear y destruir la sesión cada vez) –

1

Si está intentando implementar algo como lo hace NHibernate con su Session, creo que es una buena idea tener este tipo de patrón. Sé con certeza que en LinqToSql la implementación del objeto de contexto es más como una clase de punto de entrada que actúa como fachada. Me gustaría pensar que LinqToEntities es similar. Podría tener una implementación de fábrica para obtener un contexto de datos para su modelo en el que pueda reciclar el contexto de datos. Si va solo, considere el cuello de botella, la disponibilidad y la responsabilidad del objeto singleton.

4

Consulte this blog entry que proporciona más detalles sobre cómo crear un singleton para el contexto de Entity Framework y por qué esto no funcionaría en ASP.NET y se presenta una solución que hace algo similar a lo que sugiere.

Cuestiones relacionadas