Шаблон репозитория - слишком много методов - PullRequest
8 голосов
/ 14 февраля 2012

Я часто вижу примеры шаблонов репозитория, которые выглядят так:

public interface IRepository<T>
{
    T GetById(int id);
    IEnumerable<T> GetAllByName(string name);
}

Но как вы справляетесь со случаями, когда вам может потребоваться выполнить сложный поиск?Я не думаю, что было бы хорошей идеей добавить в интерфейс множество методов, которые бы в итоге выглядели так:

IEnumerable<T> GetAllByFirstName(string name);
IEnumerable<T> GetAllByLastName(string name);
IEnumerable<T> GetAllByFirstAndLastName(string name);
IEnumerable<T> GetAllByAddress(string name);
...
...
...

Ответы [ 6 ]

6 голосов
/ 14 февраля 2012

Используйте Predicate Builder для динамического построения условия where

public interface IRepository<T>
{
    T GetById(int id);

    IEnumerable<T> GetAllBy(Expression<Func<T, bool>> predicate);
}

Тогда постройте условия

  var predicate = PredicateBuilder.True<Customer>();
  if (!string.IsNullOrEmpty(FirstName))
  {
       predicate = predicate.And(d => d.FirstName.Contains(FirstName));
  }

  if (!string.IsNullOrEmpty(LastName))
  {
       predicate = predicate.And(d => d.LastName.Contains(LastName));
  }

  var products = productRepo.GetAllBy(predicate);

Создать класс для соответствия критериям поиска

public class CustomerFilterCriteria
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string Address { get; set; }

}

public interface IRepository<T>
{
    T GetById(int id);
    IEnumerable<T> GetAllBy(CustomerFilterCriteria criteria);
}
2 голосов
/ 14 февраля 2012

Вопрос: Зачем делать хранилище универсальным, если вы собираетесь предоставлять методы, специфичные для типа (или у всех ваших сущностей есть FirstName, LastName, Address и т. Д.?).

Если для ваших базовых ресурсов данных включено дерево выражений LINQ, общая сигнатура также будет общей, например,

IEnumerable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter)

И если вы хотите, чтобы ваши запросы были «наращиваемыми», вы можете выставитьIQueryable

IQueryable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter)
1 голос
/ 14 февраля 2012

Вот методы, которые я предоставляю для своего шаблона хранилища,

 public interface IRepository<T> : IDisposable
    {
        void Create(T entity);

        void Delete(T entity);

        void Update(T entity);

        IQueryable<T> GetAll();

        T GetBy(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes);
    }

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

Прочитайте мою статью об этом здесь http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

0 голосов
/ 14 февраля 2012

имеют общий репозиторий

public interface IRepository<T>
{
    T GetById(int id);
    IEnumerable<T> GetAllBy(Expression<Func<T, bool>> predicate);
}

тогда есть более конкретные репозитории

public interface IUserRepository : IRepository<T>
    {
        User GetByName(string name);
    }

таким образом, ваш общий репозиторий обрабатывает все содержимое CRUD и ваши действительные репозитории что угодно

0 голосов
/ 14 февраля 2012

«Метод get» может быть собственным интерфейсом:

    public interface IGetMethod<T>
    {
       IEnumerable<T> get(String name);
    }

    class GetByName<T> : IGetMethod<T>
    {
       IEnumerable<T> get(String name)
       {
           // ...
       }
    }

    public interface IRepository<T>
    {

        IEnumerable<T> GetAllByMethod(IGetMethod<T> method, string name);
    }
0 голосов
/ 14 февраля 2012

Вы можете добавить модель фильтра и проверить, какие фильтры были заполнены следующим образом:

IEnumerable<T> GetAllByFiilter(FilterModel filter);


public class FilterModel {
   public string Lastname {get;set;}
   public string Firstname {get;set;}
}


public IEnumerable<T> GetAllByFilter(FilterModel filter) {
   if(!string.IsNullOrWhiteSpace(filter.Lastname) { 
     //add restriction
   }
   // .. etc ..
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...