Как мне обрабатывать отношения таблиц с шаблоном хранилища? - PullRequest
12 голосов
/ 12 мая 2011

Я внедряю шаблон репозитория как часть сайта ASP.NET MVC. Большинство примеров репозиториев, которые я видел, довольно просты. Например, вот типичный абстрактный интерфейс хранилища.

public interface IRepository<TEntity>
{
    IQueryable<TEntity> All();
    TEntity FindBy(int id);
    TEntity FindBy(Expression<Func<TEntity, bool>> expression);
    IQueryable<TEntity> FilterBy(Expression<Func<TEntity, bool>> expression);
    bool Add(TEntity entity);
    bool Update(TEntity entity);
    bool Delete(TEntity entity):
}

Мне понятно, как вы будете использовать подобное хранилище для добавления, обновления, удаления или получения объектов одного типа. Но как вы справляетесь с созданием и управлением отношениями «один ко многим» или «многие ко многим» между различными типами?

Скажем, у вас есть тип Item, где каждый элемент назначен на Category. Как бы вы сделали это назначение через хранилище? Должно ли это быть до Update(Category c) и / или Update(Item i) методов, чтобы выяснить, какие отношения необходимо установить с обновляемым элементом или из него? Или должен быть явный метод AssignCategoryToItem(Item i, Category c)?

Если есть какая-то разница, я использую Fluent NHibernate для реализации своих конкретных репозиториев.

Ответы [ 2 ]

2 голосов
/ 12 мая 2011

Как ваше приложение справляется с назначением категории для элемента?

Имеет ли это:

  1. Позволяет пользователю просматривать элемент и назначать ему категорию
  2. Позволяет пользователю просматривать категорию, а затем добавлять к ней элементы

Пусть ваше приложение диктует, какой метод вы выберете.

Это порождает идею иметь слой Business Logic/Services и иметь дело с совокупными корнями . В моих приложениях у меня всегда есть слой services, где вся бизнес-логика. Я обнаружил, что благодаря этому мое приложение стало проще для понимания и поддержки / рефакторинга. (Примечание: я также использую универсальные репозитории и помещаю поиск сложных репозиториев в отдельные функции в соответствующем классе обслуживания)

В вашем services слое у вас будет функция с именем AssignCategoryToItem, которая затем будет принимать категорию (совокупный корень), а затем вы добавите элемент к этому category и сохраните изменения - хотя я предпочел бы передать IDs категории и извлечь ее из базы данных перед обновлением.

0 голосов
/ 12 мая 2011

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

Например, ...

public interface IProductRepository
{
    IList<Product> GetProductsInCategory(Category c);
    Product GetProductBy(int id);
    IList<Category> GetActiveProductCategories();
}

Тогда в вашей конкретной реализации IProductRepository вы будете использовать общий репозиторий, запрашивать связанные объекты и присоединяться к ним по мере необходимости.

...