2010-08-11 3 views
2

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

Для правильного управления получаемыми объектами репозитории передаются 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 имеет свойство, соответствующее другой объект, Бар:

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

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

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

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

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

Благодаря

David

ответ

2

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

+0

Теперь вот ответ! В каком состоянии находится NHibernate 3? – David

+1

Это довольно стабильно. –

0

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

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

+0

Я не указал полный код для этих классов и интерфейсов! Только биты, имеющие отношение к моему вопросу! – David

+0

Это имеет смысл в отношении единицы работы. Я все еще думаю, что вам нужно переосмыслить свой дизайн, потому что вы хотите противоречить друг другу. – Paco

+0

Я не думаю, что я пытаюсь сделать противоречивые вещи. Вы можете сказать мне, что вы имеете в виду? – David