Шаблон хранилища - PullRequest
       36

Шаблон хранилища

7 голосов
/ 02 марта 2011

Я видел много реализаций шаблона репозитория. В частности, 2 типа

  1. Они предоставляют общий репозиторий, к которому можно обращаться, и ожидает, что выражение lamba из класса обслуживания получит данные из базы данных.

  2. Напишите методы для получения данных из базы данных на основе бизнес-требований и инкапсулируйте логику (даже лямбду) получения данных.

Какой подход лучше?

Ответы [ 2 ]

13 голосов
/ 02 марта 2011

Я действительно предпочитаю второй.

Даже я видел статьи ведущих блоггеров о мире .NET, для меня запросы в репозитории являются злом в репозитории.

Причины:

  1. Хранилище похоже на коллекцию объектов, но хранится везде, где определена его реализация.

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

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

Queryable уничтожает большинство из этих пунктов и / или причин.

Например, почему вы должны создать GetProductByName , GetProductByCode , если вы можете сделать это с помощью LINQ на IQueryable?

И Queryable плохо работает в n-уровневых сценариях, поскольку у вас не будет доступа к соединению с базой данных на другом уровне, чем тот, который возвратил отложенный набор.

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

Queryable похож на разработку GetAll метода. Какой смысл GetAll в хранилище? Репозиторий будет извлекать все доменные объекты, а вы будете фильтровать их в бизнесе. Но ... Подождите ... Репозиторий не должен извлекать доменные объекты по некоторым критериям, не так ли?

Хотя я нахожу, что queryable несовместим с репозиторием, разработка и реализация некоторого метода репозитория, который принимает лямбда-выражение или любой делегат для того, чтобы дать какой-то фильтр или поведение, для меня, подойдет. Это не отложенное выполнение, это делегирование.

1 голос
/ 02 марта 2011

Я предпочитаю первый.

Версия с запросом лучше, потому что она требует меньше кода и более гибкая .

Вам не нужно заранее знать, что вы ищете.

  // instead of repository.FindByMinimumAge(18)
  customerList = repository.Find<Customer>(c => c.Age >= 18)

При втором подходе ваш Repository-Interface должен содержать метод FindByMinimumAge(int minimumAge) (и methodFindByName и метод ....)

обновление

Интерфейс хранилища выглядит следующим образом.

public interface IRepository<T> where T : class
{
    IEnumerable<T> Find(Expression<Func<T, bool>> where);
    ...
}

Это может быть реализовано, например, с помощью NHibernate, Linq2Sql или "Mock with a arraylist".

...