Как мне обработать отношения таблиц с шаблоном репозитория?

Я реализую шаблон репозитория как часть сайта 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 для реализации своих конкретных репозиториев.


person Eric Anastas    schedule 11.05.2011    source источник


Ответы (2)


Как ваше приложение обрабатывает присвоение категории элементу?

Имеет ли это:

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

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

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

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

person Omar    schedule 12.05.2011
comment
Хорошо, я думаю, это имеет смысл. Одна вещь, в которой я не уверен, - это то, какая логика будет идти в классах сервисов, а какая - в моих реальных классах модели? - person Eric Anastas; 18.05.2011
comment
Пусть ваши классы моделей просто представляют модели / объекты приложения. Не вкладывайте в них логику - делайте их простыми. Пусть ваши классы обслуживания позаботятся о тяжелой работе - например, о вызовах базы данных, сложной бизнес-логике / проверке. Пусть ваши модели будут объектами, которые вы используете для передачи информации из вашего репозитория / базы данных на уровень сервисов и обратно. - person Omar; 18.05.2011

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

Такие как...

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

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

person Baldy    schedule 12.05.2011