Realmente depende de cómo desea exponer su repositorio/almacén de datos.
No estoy seguro de lo que quiere decir con "el contexto se cerrará, por lo tanto, no puedo hacer la lógica de negocios". Haga su lógica de negocio dentro de la declaración using. O si su lógica comercial está en una clase diferente, entonces continuemos. :)
Algunas personas vuelven colecciones concretas de su depósito, en cuyo caso se puede envolver el contexto de la instrucción using:
public class ArticleRepository
{
public List<Article> GetArticles()
{
List<Article> articles = null;
using (var db = new ArticleNetEntities())
{
articles = db.Articles.Where(something).Take(some).ToList();
}
}
}
ventaja de que está satisfaciendo la buena práctica con conexiones - abrir tan tarde como puedes, y cierra tan pronto como puedas.
Puede encapsular toda la lógica de su negocio dentro de la instrucción using.
Las desventajas: su Repositorio se da cuenta de la lógica de negocios, que personalmente no me gusta, y termina con un método diferente para cada escenario en particular.
segunda opción - vuelva a crear un contexto como parte del repositorio y haga que implemente IDisposable.
public class ArticleRepository : IDisposable
{
ArticleNetEntities db;
public ArticleRepository()
{
db = new ArticleNetEntities();
}
public List<Article> GetArticles()
{
List<Article> articles = null;
db.Articles.Where(something).Take(some).ToList();
}
public void Dispose()
{
db.Dispose();
}
}
Y luego:
using (var repository = new ArticleRepository())
{
var articles = repository.GetArticles();
}
O el -tercera opción de (mi favorito), el uso de inyecciones dependencia.Desacoplar todo el contexto del trabajo desde su repositorio, y dejar que el DI contenedor de eliminación de la manija de los recursos:
public class ArticleRepository
{
private IObjectContext _ctx;
public ArticleRepository(IObjectContext ctx)
{
_ctx = ctx;
}
public IQueryable<Article> Find()
{
return _ctx.Articles;
}
}
Su elegido contenedor DI inyectará ObjectContext concreto en la creación de instancias del repositorio, con una duración configurada (Singleton, HttpContext, ThreadLocal, etc.) y deshacerse de él en función de esa configuración.
Lo tengo configurado para que cada solicitud HTTP reciba un nuevo contexto. Cuando la Solicitud finalice, mi contenedor DI eliminará automáticamente el contexto.
También utilizo el patrón Unidad de trabajo aquí para permitir que varios repositorios funcionen con un contexto de objeto.
Es posible que también haya notado que prefiero devolver IQueryable de mi Repositorio (a diferencia de una Lista concreta). Mucho más poderoso (aunque arriesgado, si no comprende las implicaciones). Mi capa de servicio realiza la lógica comercial en IQueryable y luego devuelve la colección concreta a la IU.
Esa es mi opción más poderosa, ya que permite un Repositorio simple como el de Heck, la Unidad de Trabajo administra el contexto, la Capa de Servicio maneja la Lógica de Negocios, y el Contenedor DI maneja la vida/eliminación de recursos/objetos.
Avíseme si desea obtener más información al respecto, ya que hay mucho que ofrecer, incluso más que esta respuesta sorprendentemente larga. :)
Sin preocupaciones. :) Mira algunas de mis otras preguntas/respuestas: he estado lidiando con esto recientemente. No tenía la intención de que esta respuesta fuera tan larga, pero creo que me dejé llevar, después de todo, es un tema bastante complicado. :) – RPM1984
¿Podría explicarme más sobre cómo usa el patrón de unidad de trabajo? Pensé que EF ObjectContext es realmente una UoW. – Santhos
Lo que me gustaría saber es qué agrega esta versión final? Simplemente parece una abstracción adicional sobre el marco de la entidad, que ya es una abstracción, ya que el marco de la entidad ya implementa la Unidad de trabajo y el Repositorio en sí mismo. ¿Por qué usar esta clase de repositorio en lugar de la entidad datacontext en sí? – Tobberoth