28 votes

Modèle de référentiel dans le cadre Entity 4 quand devrions-nous disposer?

Nouveau EF et j'ai remarqué que l'utilisation d'un modèle de référentiel peut vraiment simplifier les choses et me permettra de faire quelques moqueries trop.So far So good.

Ma Question

Une utilisation typique de l'objectContext est de détruire le plus rapidement possible, voir ci-dessous

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

En utilisant le modèle de Référentiel, j'ai remarqué que personne n'utilise en fait le "à l'Aide de Modèle" par exemple

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

Si l'idée que nous devrions jeter le contexte dès que possible, sinon la mémoire pourrait fuir ou d'obtenir de très grand?

Quelqu'un peut-il préciser? Merci beaucoup.

45voto

Ladislav Mrnka Points 218632

Oui, vous devriez jeter contexte, même si vous utilisez référentiel. Il n'est pas clair quels sont les avantages de votre Référentiel de mise en œuvre de vous donner parce que vous êtes encore fournir ObjectContext du constructeur paramètre, n'est-ce pas?

De l'OMI, la raison principale de l'utilisation du Référentiel et de la coutume UnitOfWork est la persistance de l'ignorance = cachent EF code de la haute-application de couches parce ObjectContext + ObjectSet sont eux-mêmes la mise en œuvre du référentiel et de l'unité de modèles de travail.

Si je suis en utilisant le référentiel, je suis toujours à l'habillage de l'ensemble EF code, de sorte que le public interface de mon référentiel ne fournit pas d'informations sur les EF de l'infrastructure connexe. Dans ce cas, c'est à moi comment je traite avec ObjectContext.

Pour la simple et directe de la CRUD scénarios, je peux enrouler le contexte de la création et de la disposition dans chaque référentiel méthode. Dans des scénarios plus complexes, je suis en classe supplémentaire - UnitOfWork (UoW), qui encapsule le contexte de création et de mise au rebut et il déclenche l'enregistrement des modifications dans la base de données. Il agit également en tant que par défaut pour tous les référentiels et passe instance de créé contexte dans les référentiels des constructeurs.

La plupart du temps, je suis à la programmation des services ou des applications web, donc je fais face à des objets détachés. Je suis toujours à l'aide de la seule UoW exemple pour le traitement de la demande. Ainsi, le UoW est créée au début du traitement de la requête et publié à la fin du traitement de la requête. En cas de WinForms / WPF applications et des objets attachés, je pense, la bonne idée est d'avoir UoW / ObjectContext exemple "par la forme" - il y a de l'article décrivant cette approche avec NHibernate session (même que EF ObjectContext) dans MSDN magazine.

Certaines de départ de la mise en œuvre de UnitOfWork d'un Référentiel et de modèles de:

Contexte titulaire et de l'abrégé de l'usine pour les dépôts

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

  SaveChanges();
}

Référentiel pour la maison d'entités

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

Jetable de mise en œuvre de UnitOfWork emballage Enitity cadre

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

La Base du référentiel de mise en œuvre

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

Utilisation lors de la sélection de données

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

L'utilisation lorsque modifiant les données

using (var uow = new UnitOfWork(connectionString))
{
  uow.MyEntitiesRepository.Update(entity);
  uow.SaveChanges();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X