Является ли это правильным способом использования ThenFetch () для загрузки нескольких коллекций? - PullRequest
9 голосов
/ 03 августа 2010

Я пытаюсь загрузить все коллекции с нетерпением, используя NHibernate 3 alpha 1 .Мне интересно, если это правильный способ использования ThenFetch ()?

Свойства с множественными именами являются коллекциями.Остальные - всего лишь один объект.

            IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
            from mi in db
            where mi.RunDate == runDate
            select mi).Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.PrimaryOwners)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.SecondaryOwners)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.Predecessors)
                .Fetch(mi => mi.Milestone)
                .ThenFetch(m => m.Function)
                .Fetch(mi => mi.Milestone)
                .ThenFetchMany(m => m.Jobs)
                .ThenFetch(j => j.Source)
                ;

Я думал об этом на форумах NHibernate , но, к сожалению, доступ к группам Google запрещен там, где я.Я знаю, что Фабио здесь, так что, может быть, ребята из команды NHibernate могут пролить свет на это?Спасибо

Ответы [ 4 ]

10 голосов
/ 16 августа 2012

Очевидно, что в таком случае нет "правильного" способа использования ThenFetch.Ваш пример работает нормально, но созданный SQL содержит много соединений с Milestone, что не так.

Использование IQueryOver вместо IQueryable позволяет использовать сложный синтаксис Fetch:

Fetch(p => p.B) 
Fetch(p => p.B.C) // if B is not a collection ... or 
Fetch(p => p.B[0].C) // if B is a collection ... or 
Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method) 

Так что в вашем случае это будет:

query // = session.QueryOver<X>()
    .Fetch(mi => mi.Milestone).Eager
    .Fetch(mi => mi.Milestone.PrimaryOwners).Eager
    .Fetch(mi => mi.Milestone.SecondaryOwners).Eager
    .Fetch(mi => mi.Milestone.Predecessors).Eager
    .Fetch(mi => mi.Milestone.Function).Eager
    .Fetch(mi => mi.Milestone.Jobs).Eager
    .Fetch(mi => mi.Milestone.Jobs.First().Source).Eager
3 голосов
/ 02 января 2011

Единственное, чего вам не хватает, так это того, что вы должны использовать FetchMany (), а ThenFetchMany () - это дочернее свойство коллекции.

1 голос
/ 30 июля 2014
        IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
        from mi in db
        where mi.RunDate == runDate
        select mi);

var fetch = milestoneInstances.Fetch(f => f.Milestone);
fetch.ThenFetch(f => f.PrimaryOwners);
fetch.ThenFetch(f => f.SecondaryOwners);
//...
0 голосов
/ 16 августа 2012

Как сказал leora, убедитесь, что при получении дочерних коллекций, которые вы используете

FetchMany()

ThenFetchMany()

Новая выборка, должна быть получена из корня, но это не всегда происходит.Иногда вам нужно создавать их как отдельные запросы или использовать Criteria Futures для пакетной обработки нескольких выборок.

...