这是使用 thenFetch() 加载多个集合的正确方法吗?

发布于 2024-09-12 15:17:51 字数 1184 浏览 11 评论 0原文

我正在尝试使用 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 群组是。我知道 Fabio 在这里,所以也许来自 NHibernate 团队的人可以解释一下这一点? 谢谢

I'm trying to load all the collections eagerly, using NHibernate 3 alpha 1. I'm wondering if this the right way of using ThenFetch()?

Properties with plural names are collections. The others are just a single object.

            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)
                ;

I thought of asking this in the NHibernate forums but unfortunately access to google groups is forbidden from where I am. I know Fabio is here, so maybe the guys from the NHibernate team can shed some light on this?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

泪眸﹌ 2024-09-19 15:17:51

显然,在这种情况下没有“正确”的方法来使用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

Apparently, there's no "right" way to use ThenFetch in such a case. Your example works fine but SQL produced contains many joins to Milestone, which isn't that right.

Using IQueryOver instead of IQueryable allows you to use complex syntax in 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) 

So in your case it would be:

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
木森分化 2024-09-19 15:17:51

您缺少的一件事是您应该使用 FetchMany() ,然后 FetchMany() 是子属性是一个集合。

The one thing you are missing is that you should use FetchMany() and ThenFetchMany() is the child property is a collection.

断念 2024-09-19 15:17:51
        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);
//...
        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);
//...
ㄖ落Θ余辉 2024-09-19 15:17:51

正如 leora 所说,确保在获取子集合时使用

FetchMany()

ThenFetchMany()

新的 Fetch,应该从根中获取,但这并不总是发生。有时您需要将它们创建为单独的查询或使用 Criteria Futures 来批量进行多个获取。

As leora said, make sure when fetching children collections that you use

FetchMany()

ThenFetchMany()

A new Fetch, should pick up from the root, but this does not always happen. Sometimes you need to create them as separate queries or use Criteria Futures to batch up a multiple fetch.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文