2012-06-19 15 views
5

Ho appena visto la realizzazione di GenericRepository:GenericRepository ed EF. È buono?

namespace ContosoUniversity.DAL 
{ 
    public class GenericRepository<TEntity> where TEntity : class 
    { 
     internal SchoolContext context; 
     internal DbSet<TEntity> dbSet; 

     public GenericRepository(SchoolContext context) 
     { 
      this.context = context; 
      this.dbSet = context.Set<TEntity>(); 
     } 

     public virtual IEnumerable<TEntity> Get(
      Expression<Func<TEntity, bool>> filter = null, 
      Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, 
      string includeProperties = "") 
     { 
      IQueryable<TEntity> query = dbSet; 

      if (filter != null) 
      { 
       query = query.Where(filter); 
      } 

      foreach (var includeProperty in includeProperties.Split 
       (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) 
      { 
       query = query.Include(includeProperty); 
      } 

      if (orderBy != null) 
      { 
       return orderBy(query).ToList(); 
      } 
      else 
      { 
       return query.ToList(); 
      } 
     } 

     public virtual TEntity GetByID(object id) 
     { 
      return dbSet.Find(id); 
     } 

     public virtual void Insert(TEntity entity) 
     { 
      dbSet.Add(entity); 
     } 

     public virtual void Delete(object id) 
     { 
      TEntity entityToDelete = dbSet.Find(id); 
      Delete(entityToDelete); 
     } 

     public virtual void Delete(TEntity entityToDelete) 
     { 
      if (context.Entry(entityToDelete).State == EntityState.Detached) 
      { 
       dbSet.Attach(entityToDelete); 
      } 
      dbSet.Remove(entityToDelete); 
     } 

     public virtual void Update(TEntity entityToUpdate) 
     { 
      dbSet.Attach(entityToUpdate); 
      context.Entry(entityToUpdate).State = EntityState.Modified; 
     } 
    } 
} 

qui: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application e penso che sia davvero bello, ma mi piacerebbe farti una domanda. quali sono i pro e i contro di questo approccio con la realizzazione separata (ciascun repository di entità in una classe separata)?

risposta

1

Questo è più gusto personale di ogni altra cosa. Personalmente non mi piace il termine Repository perché è troppo generico e il significato/scopo del repository è stato perso. Trovo che i repository siano spesso generici e ripetitivi come se ogni entità avesse bisogno del proprio repository. e poi il repository ottiene troppi metodi off per l'interrogazione. molto presto si finisce con una classe di Dio per l'accesso ai dati. Questa è stata la mia esperienza.

con il repository generico è possibile utilizzare l'ereditarietà in sottoclasse per entità specifiche per query on-off. Preferisco la composizione sull'ereditarietà, quindi un'altra ragione per cui evito il termine/uso dei repository.

invece mi piace pensare all'accesso ai dati come query (leggi) & oggetti di comando (scrittura). dove ogni oggetto ha 1 metodo per recuperare una proiezione specifica (query) dei dati o modificare i dati persistenti (comando).

alla fine fintanto che il tuo team & conosce l'architettura e il codice è gestibile, hai una soluzione solida. Non è davvero buono o cattivo.

+0

Thx per la risposta –

1

Anche se si decide di avere classi concrete Repository per ogni entità, è comunque assolutamente consigliabile utilizzare un repository generico come base in modo da non duplicare il codice e verificare le funzionalità comuni in un posto.

Realisticamente, non ci sono contro in questa pratica. Se hai bisogno di fondere il modo in cui uno dei metodi funziona per un'entità specifica, devi solo sostituirlo, correggerlo e assicurarti che sia coperto da un test unitario.

+0

Quindi, è un "proiettile d'argento" per la realizzazione del modello di repository? –

+0

"Silver bullet" è una parola caricata ... no, non posso dire che sia così; C'è merito all'argomento secondo il quale può diventare un'astrazione che perde, in quanto, per completare in modo efficiente un'attività, potrebbe essere necessario utilizzare funzionalità specifiche ORM ed esporre genericamente tale funzionalità può essere un incubo. Tuttavia, il 95% delle volte, non ne ho bisogno, e come dice @Steven nella sua risposta, sono (IMHO) troppo utili per essere ignorati. Vedere la mia risposta qui per maggiori dettagli e come gestisco il 5% delle situazioni che sono complicate con i repository generici http://stackoverflow.com/a/10925510/64750 – HackedByChinese

+0

Thx per la risposta e il collegamento –

1

Ci sono diverse opinioni sull'uso di decoratori generici. Ci sono fondamentalmente due campi. Il primo campo trova il repository generico un'astrazione che perde, il che significa che spesso non si sta davvero astrarre l'origine dati con esso. Non dovrebbe quindi essere usato affatto. Leggi per esempio this answer.

Sono al secondo campo. So che è un'astrazione che perde, ma un repository generico (specialmente con il supporto IQuerable), porta semplicemente a un codice troppo espressivo e verificabile, da ignorare. Ho scritto an article about generic repositories. È un approccio alternativo per avvicinarsi ai tuoi punti di collegamento. Offre un approccio diverso agli archivi generici, con particolare attenzione alla manutenibilità e alla testabilità. Potresti trovarlo utile

+0

Grazie mille per la tua risposta e articolo! –

Problemi correlati