Подтвердить что ты не робот

Один большой репозиторий против многих маленьких?

В моей базе данных есть несколько таблиц продуктов:

  • ProductTypes
  • ProductCategories
  • ProductCategoryItems
  • ProductInventory

Как я вижу это сейчас, я могу сделать IProduct, который будет иметь такие методы, как:

  • FindAllTypes()
  • FindAllCategories (int typeId)
  • FindAllItems (int categoryId)

Или, я могу разделить каждый, чтобы имитировать структуру таблицы: IProductType, IProductCategory и т.д.

Есть ли причина переходить друг с другом?

4b9b3361

Ответ 1

Идея репозиториев заключается в том, чтобы делегировать каждому из них ответственность за единый объект. В этом случае рекомендуется создать репозиторий для каждого объекта. Вы также можете использовать большой репозиторий, но это не лучшее решение. В итоге вы получите ОГРОМНЫЙ класс с множеством методов и очень плотно связанными. Также трудно дать техническое обслуживание.

Ответ 2

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

Мне нравится иметь базу Repository<T>, которая выполняет общие операции, такие как GetById и GetAll. Обычно у меня все мои репозитории наследуют этот базовый класс, чтобы получить общие методы бесплатно, поэтому мне не нужно переписывать один и тот же код.

Ответ 3

По-моему, это очень зависит от модели бизнес-домена, очень важно определить, каковы ваши основные бизнес-объекты. Не обязательно каждая таблица в БД непосредственно сопоставляется с бизнес-объектом. Таблицы - это просто представления вашего одного или многих объектов нормализованным образом для реляционных баз данных.

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

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

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

Надеюсь, что это поможет.

Ответ 4

Я не согласен с остальными (редактировать: кроме Исаака). Маленькие репозитории - это фасад (а не шаблон).

Если типы сущностей связаны (имеют свойства навигации друг к другу), то они не являются действительно разделяемыми.

Изменение одного типа сущности и фиксация изменений может привести к изменению других.

Кроме того, вы не можете создать небольшой репозиторий над одной и той же единицей работы, поскольку ORM имеет ограниченное количество объектов, сопоставленных с базой данных.

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

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

Каждый корень должен был специально ввести команды add, remove, getbykeys, query и т.д.

Единица работы должна иметь комминансы и аналогичные методы на ней.

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

Пример:

// Create one of these
interface IUnitOfWork
{
    void Commit();
}

// Create one of these
interface IEntitySet<TEntity> where TEntity : class
{
    void Add(TEntity entity);
    void Remove(TEntity entity);
    TEntity Create<TSpecificEntity>() where TSpecificEntity : TEntity;

    IQueryable<TEntity> Query();
}

// Create one of these per entity type
interace IEntitySetOfTEntity1 : IEntitySet<Entity1>
{
    TEntity1 GetByKeys(int key1);
}

interace IEntitySetOfTEntity2 : IEntitySet<Entity2>
{
    TEntity1 GetByKeys(short key1, short key2);
}

// Create one of these per separatable domain
interface IDomain1UnitOfWork : IUnitOfWork
{
    IEntitySetOfTEntity1 Entity1s
    {
        get;
    }

    IEntitySetOfTEntity2 Entity2s
    {
        get;
    }
}

Все эти интерфейсы и их реализации могут быть автоматически сгенерированы.

Эти интерфейсы и их реализации очень легки и ни в коем случае не являются "ОГРОМНЫМ классом с множеством методов". Поскольку они могут быть автоматически сгенерированы, обслуживание легко.

Конкретные функциональные возможности могут быть добавлены к интерфейсам IDomain1UnitOfWork, IEntitySetOfTEntity1 и аналогичным образом, используя:
а. методы расширения
б. частичные интерфейсы и классы (менее рекомендуется, так как это приводит к менее чистому DAL)

Подобные интерфейсы IEntitySetOfTEntity1 могут быть отброшены, если вы используете методы расширения для добавления методов GetByKeys() в IEntitySet <Entity1 > .