Выборка инкапсуляции стратегии для Entity Framework 4.1 и NHibernate - PullRequest
3 голосов
/ 26 мая 2011

Я создал проект для тестирования NHibernate 3+ и Entity Framework 4.1, поместив его в репозиторий, сделав его очень тестируемым с использованием интерфейсов и т. Д.

Я не хочу показывать ORM вне репозиториев (я даже не выставляю IQueryables). Все должно быть обработано в этом слое, и до тех пор, пока я не попытался обработать извлечение абстрактным способом, все было хорошо.

В Microsoft добавление активной загрузки использует либо магические строки (yuck), либо выражения Linq (yay) в функции Include. Их синтаксис выглядит примерно так:

IQueryableThing.Include(o => o.Person);
IQueryableThing.Include(o => o.Company.Contact);
IQueryableThing.Include(o => o.Orders.Select(p => p.LineItem.Cost);

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

Это довольно приятная реализация.

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

IQueryableThing.Fetch(o => o.Person);
IQueryableThing.Fetch(o => o.Company).ThenFetch(o => o.Contact);
IQueryableThing.FetchMany(o => o.Orders).ThenFetch(p => p.LineItem).ThenFetch(q => q.Cost);

(я не уверен, что в третьей строке правильный синтаксис)

Я могу инкапсулировать список выражений в отдельный класс, а затем применить эти выражения к IQueryable внутри этого класса. Поэтому мне нужно стандартизировать синтаксис выражений Microsoft, а затем преобразовать его в синтаксис NHibernate, обходя дерево выражений и перестраивая каждое выражение.

Это действительно сложная часть. Я должен поддерживать определенный порядок операций, чтобы вызвать правильную функцию для IQueryable (должен начинаться либо с Fetch, либо с FetchMany, каждый из которых должен быть «ThenFetch» ​​или «ThenFetchMany»), что мешает мне использовать в классе ExpressionVisitor.

Edit: Наконец, я создал анализатор выражений, который будет принимать любой уровень вложенности свойств, коллекций и селекций в коллекциях и создавать массив выражений. К сожалению, встроенные методы расширений Fetch не принимают LambdaExpression в качестве параметра.

Часть, на которой я застрял в настоящее время , не может использовать встроенные определения Fetch из nHibernate. Похоже, мне, возможно, придется напрямую нажимать на функции библиотеки Remotion или регистрировать собственные методы расширения, которые удовлетворят их анализатор.

Фанки.

1 Ответ

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

Вы пробовали использовать NHiberanteUtil.Initialize()?Я не пытался делать то, что вы делаете, но я думаю, что Initialize будет работать как Include().

...