Как установить стратегию извлечения NHibernate Linq через фасадный слой - PullRequest
2 голосов
/ 11 августа 2010

Я использую NHibernate для доступа к данным, но обращаюсь к нему через фасадный слой. Этот уровень состоит из интерфейсов для репозиториев, а также интерфейса IUnitOfWork, который соответствует объекту ISession.

Для правильного управления извлеченными объектами в их конструктор передаются репозитории IUnitOfWork, а для загрузки используется IUnitOfWork.

IUnitOfWork содержит свойство All, которое извлекает все сущности класса как IQueryable (для последующей фильтрации). Таким образом, метод хранилища для извлечения всех сущностей, созданных в этом году, может выглядеть следующим образом:

NB : это не полный код для этих интерфейсов и классов! Только код, соответствующий моему вопросу.

Интерфейс IUnitOfWork:

IQueryable<T> GetList<T>();

Класс бетона UnitOfWork:

public IQueryable<T> GetList<T>()
{
  return _session.Linq<T>();
}

Интерфейс IFooRepository

IQueryable<Foo> All { get; }
IEnumerable<Foo> ThisYearsFoos{ get; }

FooRepository класс бетона

public IQueryable<Foo> All
{
  get { return _unitOfWork.GetList<Foo>(); }
}

public IEnumerable<Foo> ThisYearsFoos
{
  get { return All.Where(x => x.DateCreated > new DateTime(2010,1,1);}
}

Я хотел бы добавить функциональность для указания стратегий выборки, чтобы связанные с ними объекты могли загружаться с нетерпением. Допустим, у Foo есть свойство, соответствующее другому объекту, Bar:

public class Foo
{
    public Bar {get;set;}
}

Файл сопоставления указывает, что Bar загружен отложенным образом, но в моем свойстве репозитория ThisYearsFoos я хотел бы указать, что Bar должен загружаться с нетерпением, чтобы избежать выбора N + 1.

В Linq to NHibernate мы можем указать активную выборку, используя метод расширения Expand (). Однако этот метод расширения относится к типу NHibernateQueryable, а метод GetList интерфейса IUnitOfWork знает только о IQueryable.

Очевидно, я не хочу, чтобы интерфейс IUnitOfWork знал об INHibernateQueryable, поскольку он не должен знать о NHibernate.

Используя дизайн, который я указал выше, есть ли способ сделать это, о котором я не смог придумать? Или мой дизайн нуждается в переосмыслении?

Спасибо

David

Ответы [ 2 ]

2 голосов
/ 11 августа 2010

Обновление до NHibernate 3.x. Новый метод, который соответствует Expand (Fetch), работает на IQueryable.

0 голосов
/ 11 августа 2010

Вы говорите несколько противоречивых вещей: - Вы не хотите выставлять интерфейс - Вы хотите использовать этот интерфейс

Это невозможно. Вы должны переосмыслить свой дизайн. Вы используете термин «единица работы» для другой вещи, чем большинство людей. Большинство людей ожидают, что в интерфейсе единицы работы будут методы Commit и RollBack, но не некоторые IQueryable.

...