NHibernate Linq Eager Загрузка с универсальным репозиторием - PullRequest
3 голосов
/ 12 ноября 2010

В настоящее время мы используем общий репозиторий для всех наших сущностей, который предоставляет IQueryable (используя поддержку NH3 linq), который затем используется нашим сервисным уровнем для построения конкретных запросов.

Теперь мне нужно с нетерпением загрузитьассоциация.Есть ли способ, которым я могу предоставить IQueryable и передать необязательные выражения выборки?Проблема, которую я вижу, состоит в том, что Fetch должен стоять последним в выражении (согласно http://mikehadlow.blogspot.com/2010/08/nhibernate-linq-eager-fetching.html).

. Мне любопытно, как другие достигли этого.

Я подумал, возможно, о прохождении спецификаций Linqв хранилище, чтобы они могли быть оценены до вызова Fetch. Однако мне все равно потребуется какой-то способ передачи выражений Fetch.

Спасибо, Бен

Ответы [ 3 ]

3 голосов
/ 12 ноября 2010

Я использую перегрузки моих вызовов репозитория FindOne и FindAll для достижения этого, что-то вроде:

Function FindOne(ByVal spec As ILinqSpecification(Of T)) As T
Function FindOne(ByVal spec As ILinqSpecification(Of T), ByVal strategy As IFetchingStrategy(Of T)) As T
Function FindAll(ByVal spec As ILinqSpecification(Of T)) As IQueryable(Of T)
Function FindAll(ByVal spec As ILinqSpecification(Of T), ByVal strategy As IFetchingStrategy(Of T)) As IQueryable(Of T)

и т.д ..

Возможно, не самый чистый подход, но он делает свою работу. Я не уверен, является ли это все еще проблемой с поставщиком trunk linq или нет, но я также могу решить, применять ли отдельный преобразователь результатов к моим результатам в сценариях FindAll в зависимости от того, используется ли моя стратегия выборки содержит коллекцию.

Моя реализация спецификации и стратегии выборки основана на тех, которые доступны в проекте ncommon .

Для справки, мой полный общий интерфейс репозитория "только для чтения" выглядит следующим образом:

Public Interface IReadOnlyRepositoryWithTypedId(Of T As IEntityWithTypedId(Of IdT), IdT)

    Function LoadById(ByVal id As IdT) As T
    Function GetById(ByVal id As IdT) As T
    Function FindOne(ByVal spec As ILinqSpecification(Of T)) As T
    Function FindOne(ByVal spec As ILinqSpecification(Of T), ByVal strategy As IFetchingStrategy(Of T)) As T
    Function GetCount() As Integer
    Function GetCount(ByVal spec As ILinqSpecification(Of T)) As Integer
    Function HasAny(ByVal spec As ILinqSpecification(Of T)) As Boolean
    Function FindAll(ByVal spec As ILinqSpecification(Of T)) As IQueryable(Of T)
    Function FindAll(ByVal spec As ILinqSpecification(Of T), ByVal strategy As IFetchingStrategy(Of T)) As IQueryable(Of T)
    Function FindAll() As IQueryable(Of T)
    Function FindAll(ByVal strategy As IFetchingStrategy(Of T)) As IQueryable(Of T)

End Interface
2 голосов
/ 29 апреля 2014

То, что я сделал, было примерно так (извините, C #): во-первых, интерфейс:

IQueryable<T> All<T>(params Expression<Func<T, Object>> [] fetchPaths);

Что касается реализации:

public IQueryable<T> All<T>(params Expression<Func<T, Object>> [] fetchPaths)
{
    var queryable = this.session.Query<T>();

    foreach (var fetchPath in fetchPaths)
    {
        queryable = queryable.Fetch(fetchPath);
    }

    return queryable;
}
2 голосов
/ 12 ноября 2010

Решением, которое я придумал, было добавление следующего к моему общему интерфейсу репозитория:

public IEnumerable<T> FindAll<TRelated>(Specification<T> specification, Expression<Func<T, TRelated>> fetchExpression);

Реализация NHibernate была:

public IEnumerable<Product> FindAll<TRelated>(Specification<Product> specification, Expression<Func<Product, TRelated>> fetchExpression) {
return session.Query<Product>()
    .Where(specification.IsSatisfiedBy())
        .Fetch(fetchExpression);

}

Я использую Linq Specs (http://linqspecs.codeplex.com).

Для получения полной информации, пожалуйста, смотрите http://blogs.planetcloud.co.uk/mygreatdiscovery/post/Eager-loading-with-NHibernate-LINQ.aspx

Однако, как указал Дэн в своем комментарии, этот выглядит каклучший способ абстрагирования таких запросов.

...