Patrón de repositorio en Entity framework 4 ¿cuándo debemos disponer?


Nuevo en EF y he notado que usar un patrón de repositorio realmente puede simplificar las cosas y me permitirá hacer algunas burlas too.So hasta ahora todo bien.

Mi Pregunta

Un uso típico del ObjectContext es destruir lo antes posible ver más abajo

using (var context = new SchoolEntities())
{    
    context.AddToDepartments(department);    
    context.SaveChanges();
}

Usando el patrón del Repositorio He notado que nadie realmente usa el" Usando el patrón " eg

using (var repository= new Repository<Student>(new MyContext))
{    
    repository.Add(myStudentEntity)  
    repository.SaveChanges();
}

Si la idea es que debemos disponer del contexto tan pronto como sea posible, de lo contrario la memoria ¿podría gotear o hacerse muy grande?

¿Puede alguien aclarar? Muchas gracias.

Author: Stijn, 2010-11-28

1 answers

Sí debe disponer de contexto incluso si está utilizando repositorio. No está claro qué ventaja le da su implementación de repositorio porque todavía está proporcionando ObjectContext como parámetro del constructor, ¿no es así?

IMO la razón principal para usar Repository y custom UnitOfWork es persistance ignorance = hidding EF code from upper application layers because ObjectContext + ObjectSet themselves are implementation of repository and unit of work patrón.

Si estoy usando repositorio, siempre estoy empaquetando todo el código EF, por lo que la interfaz pública de mi repositorio no proporciona ninguna información sobre la infraestructura relacionada con EF. En ese caso, depende de mí cómo tratar con ObjectContext.

Para escenarios CRUD sencillos, puedo envolver la creación y disposición de contexto en cada método de repositorio. En escenarios más complejos estoy usando clase adicional-UnitOfWork (UoW), que envuelve la creación y disposición de contexto y ti activa el guardado de los cambios en la base de datos. También actúa como fábrica para todos los repositorios y pasa la instancia del contexto creado a los constructores de repositorios.

La mayoría de las veces estoy programando servicios o aplicaciones web, así que estoy tratando con objetos separados. Siempre estoy usando una sola instancia de UoW para el procesamiento de solicitudes. Por lo tanto, el UoW se crea al principio del procesamiento de solicitudes y se libera al final del procesamiento de solicitudes. En el caso de aplicaciones WinForms / WPF y objetos adjuntos I creo que la buena idea es tener la instancia UOW / ObjectContext "por forma" - hay artículo describiendo este enfoque con NHibernate session (igual que EF ObjectContext) en MSDN magazine.

Algunos patrones iniciales de implementación de UnitOfWork y Repositorios:

Context holder y abstract factory para repositorios

public interface IUnitOfWork
{
  IRepository<MyEntity> MyEntityRepository { get; }
  // Repositories for other entities

  SaveChanges();
}

Repositorio para entidades separadas

public interface IRepository<T> where T : class
{
  IQueryable<T> GetQuery();
  void Insert(T entity);
  void Delete(T entity);

  // In very complex scenarios with big object graphs you will probably give up
  // using detached approach and you will always load your entities from DB before
  // deleting or updating them. In such case you will not need Update method at all.

  void Update(T entity);
}

Implementación desechable del marco de Enitity de envoltura de unidad de trabajo

public class UnitOfWork : IUnitOfWork, IDisposable
{
   private ObjectContext _context = null;

   public UnitOfWork(string connectionString)
   {
     if (String.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString");
     _context = new ObjectContext(connectionString);
   }

   private IRepository<MyEntity> _myEntityRepository;

   public IRepository<MyEntity> MyEntityRepository
   {
     get
     {
        return _myEntityRepository ?? (_myEntityRepository = new GeneralRepository<MyEntity>(_context));
     }
   }

   public void SaveChanges()
   {
     _context.SaveChanges();
   }

   public void Dispose()
   {
     Dispose(true);
     GC.SuppressFinalize(this);
   }

   protected virtual void Dispose(bool disposing)
   {
     if (disposing)
     {
       if (_context != null)
       {
         _context.Dispose();
         _context = null;
       }
     }
   }
}

Base implementación del repositorio

public class GeneralRepository<T> : IRepository<T> where T : class
{
  private ObjectSet<T> _set;
  private ObjectContext _context;


  public GeneralRepository(ObjectContext context)
  {
    if (context == null) throw new ArgumentNullException("context");
    _context = context;
    _set = context.CreateObjectSet<T>();
  }

  // Override this method for example if you need Includes
  public virtual IQueryable<T> GetQuery()
  {
    return _set;
  }

  // Override following methods if you are working with object graphs.
  // Methods do not execute operations in database. It is responsibility of 
  // UnitOfWork to trigger the execution

  public virtual void Insert(T entity)
  {
    if (entity == null) throw new ArgumentNullException("entity");
    _set.AddObject(entity);
  }

  // These impelementations are for detached scenarios like web application

  public virtual void Delete(T entity)
  {
    if (entity == null) throw new ArgumentNullException("entity");
    _set.Attach(entity);
    _set.DeleteObject(entity);
  }

  public virtual void Update(T entity)
  {
    if (entity == null) throw new ArgumentNullException("entity");
    _set.Attach(entity);
    _context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
  }
}

Uso al seleccionar datos

using (var uow = new UnitOfWork(connectionString))
{
  var entity = uow.MyEntitiesRepository.GetQuery().Single(e => e.Id == 1);
  // Do something with entity
}

Uso al modificar datos

using (var uow = new UnitOfWork(connectionString))
{
  uow.MyEntitiesRepository.Update(entity);
  uow.SaveChanges();
}
 47
Author: Ladislav Mrnka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-08 11:56:28