Как лучше всего использовать шаблон репозитория - репо на таблицу? - PullRequest
7 голосов
/ 08 июня 2011

Шаблон репозитория, кажется, хорошо работает при работе с первоначальным проектом с несколькими большими основными таблицами.

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

Например,

В записи CustomerAddress есть следующие дочерние таблицы:

-> Округ

-> Страна

-> CustomerType

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

Есть ли лучший способ / более эффективный способ сделать это?

В качестве примера, скажем, у вас есть основной репозиторий CustomerAddress, который, как я полагаю,«агрегатный корень», который наследует основные операции CRUD от базового интерфейса репо.

Ранее я сократил агрегированный корень и сразу перешел к контексту для таблиц такого типа.

например,

public Customer GetCustomerById(int id)
{
  return Get(id);
}

public IEnumerable<Country> GetCountries()
{
  return _ctx.DataContext.Countries.ToList();
}

и т.д ...

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

Ответы [ 4 ]

2 голосов
/ 08 июня 2011

Я бы, конечно, не создавал репозиторий для каждой таблицы. Напротив: я бы определил один общий репозиторий, который работает для каждой таблицы. Делая это, вы экономите много кода, а когда вы реализуете IQueryable для этого класса, это позволит вам использовать над ним запросы LINQ, и вы можете скрыть свою структуру O / RM за абстракцией, которая позволяет вам эффективно писать модульные тесты. Я написал статью об этом, см. Подделка вашего провайдера LINQ .

0 голосов
/ 28 апреля 2014

Ответ на вопрос собственный ответ : Это не имеет смысла для меня; хотя, возможно, у вас все еще был хороший вариант использования, я не следую. Пункты 1 и 2 ... если вам нужны специализированные методы, то похоже, что они принадлежат их собственным репо. Пункт 2: да, это требует реализации.

Обмен репо с меньшим репо, являющимся вопросом (нужен ли он), я действительно ценю этот вопрос / проблему, но ребята из этой темы подтолкнули меня к тому, чтобы я был в порядке с 1 репо на таблицу, включая возможность имея «сервисный слой», хотя они не приводили никаких примеров этого, и я еще не пробовал это (в настоящее время моя практика, хорошо это или плохо, состояла в том, чтобы иметь большую долю репо или создать меньшую копию это нужно):

Один репозиторий на таблицу или один на функциональный раздел?

0 голосов
/ 12 июня 2011

Я отвечаю на свой вопрос здесь, потому что, хотя предложения, безусловно, полезны, я чувствую, что у меня есть лучшее решение. Хотя мне не нужно физически создавать базовый репозиторий для каждой таблицы, поскольку у меня есть базовый базовый класс репозитория с интерфейсом (Get, Add, Remove), мне все равно необходимо:

1) написать интерфейс для доступа к любым специализированным методам (обычно это запросы)

2) написать эти реализации

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

Я решил создать новый класс SimpleRepo с интерфейсом ISimpleRepo, который предоставляет 1-2 метода. Хотя я обычно не люблю выставлять интерфейс IQueryable из класса repo i / f, я не возражаю против этого, поскольку мне нужна предоставленная гибкость. Я могу просто предоставить метод Query (), который обеспечивает ловкость. Мне может понадобиться это для специализации заказа или фильтрации.

Всякий раз, когда службе требуется использовать некоторые простые данные, передается интерфейс ISimple , где T - таблица / класс.

Теперь я избегаю необходимости создавать интерфейс / класс для этих простых фрагментов данных. Мысли кто-нибудь?

0 голосов
/ 08 июня 2011

Сначала код, который вы разместили, не является шаблоном хранилища. Где коллекция как интерфейс? Если это агрегат, он должен возвращать только агрегатный тип.

Шаблон репозитория не дает большой гибкости, когда он может выбирать различные типы. Шаблон репозитория следует интерфейсу коллекции (вставка / добавление / обновление / удаление / получение / и т. Д.), Зеркально отражая объект в памяти, и он обычно извлекается только по типу. Поэтому, если бы вы использовали шаблон репозитория, вам нужно было бы выбрать все CustomerAddresses и затем * отфильтровать страны. Я бы посоветовал вам перейти на другую схему, которая обеспечивает большую гибкость, то есть DAO.

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


На более общей ноте построить для нужд .

Никогда не создавайте классы репозитория вслепую, это кошмар обслуживания. Единственный раз, когда я бы поспорил за репо для каждой таблицы, это когда вы делаете вещи, подобные CMS, и должны иметь возможность создавать все.

Пример:

Итак, у вас есть CustomerAddress, который связывает воедино Клиента и Страну, но у вас есть другой процесс, который должен быть в состоянии CRUD для Страны. В результате вам нужен * репозиторий для манипулирования страной, и если вы следуете за СУХОЙ, вы не хотите иметь дублирующую логику для манипулирования странами. То, что у вас будет, - это Клиентский Репозиторий, который использует Страновой репозиторий.

...