2012-06-19 6 views
5

Я только что видел реализации GenericRepository:GenericRepository и EF. Это хорошо?

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

здесь: 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 и я думаю, что это очень приятно, но я хотел бы задать вам вопрос. каковы плюсы и минусы этого подхода с отдельной реализацией (каждый репозиторий объектов в отдельном классе)?

ответ

1

Это более личный вкус, чем что-либо еще. Лично мне не нравится термин «репозиторий», потому что он слишком общий, а смысл/цель репозитория потеряна. Я считаю, что репозитории часто являются типичными и повторяющимися, как если бы каждый объект нуждался в собственном репо. и тогда у репо слишком много методов для запросов. довольно скоро вы попадаете в класс богов для доступа к данным. Это был мой опыт.

с общим репо вы можете использовать наследование для подкласса для конкретных объектов для запросов включения-выключения. Я предпочитаю состав над наследованием, поэтому еще одна причина, по которой я избегаю термина/использования репозиториев.

вместо этого мне нравится думать о доступе к данным в виде запроса (read) & команду (писать) объекты. где каждый объект имеет 1 метод для получения конкретной проекции (запроса) данных или изменения сохраняемых данных (команды).

в конце, пока вы & ваша команда понимает архитектуру и код, который можно обслуживать, у вас есть прочное решение. Это не очень хорошо или плохо.

+0

Thx для вашего ответа –

1

Даже если вы решите, что для каждого объекта необходимо иметь конкретные классы Repository, он по-прежнему имеет абсолютный смысл, как минимум, использовать общий репозиторий в качестве базы, чтобы вы не дублировали код, и можете протестировать общую функциональность в одно место.

Реально, нет никаких оснований для этой практики. Если вам нужно понять, как один из методов работает для определенного объекта, вы просто переопределяете его, исправляете и проверяете, что он включен в модульный тест.

+0

Итак, это «серебряная пуля» для реализации паттернов репозитория? –

+0

«Серебряная пуля» - это загруженное слово ... нет, я не могу сказать, что это так; Существует заслуга в аргументе, что он может стать нечеткой абстракцией, тем самым для эффективного выполнения задачи вам может потребоваться использовать функциональные возможности ORM, и разоблачение этой функциональности в целом может стать кошмаром. Однако в 95% случаев мне это не нужно, и, как говорит @Steven в своем ответе, они (IMHO) слишком полезны, чтобы их можно было игнорировать. См. Мой ответ здесь для получения более подробной информации и того, как я обрабатываю 5% ситуаций, которые сложны в общих хранилищах http://stackoverflow.com/a/10925510/64750 – HackedByChinese

+0

Thx вы за свой ответ и ссылку –

1

Существует несколько мнений об использовании универсальных декораторов. В основном два лагеря. Первый лагерь обнаруживает, что общий репозиторий представляет собой пропущенную абстракцию, что означает, что вы часто не занимаетесь абстрагированием источника данных. Поэтому его нельзя использовать вообще. Читайте, например, this answer.

Я во втором лагере. Я знаю, что это непрозрачная абстракция, но общий репозиторий (особенно с поддержкой IQuerable) просто приводит к слишком выразительному и проверяемому коду, который нужно игнорировать. Я написал an article about generic repositories. Это альтернативный подход к подходу к добавлению ссылок. Это дает вам другой подход к родовым хранилищам с уделением особого внимания ремонтопригодности и тестируемости. Вы можете найти это полезным.

+0

Thx много для вас ответ и статья! –

Смежные вопросы