加入兄弟姐妹的NHibernate Fetch / ThenFetch

时间:2012-10-26 11:11:11

标签: linq nhibernate join fetch

我有以下(简化的)实体层次结构:

RootClass
->DescriptorClass
->SomeChild->DescriptorClass
           ->SomeGrandChild

如果可能的话,我想在一个查询中获取所有内容。

目前我有以下内容:

Session.Query<RootClass>().Where(/*some expressions here*/)
                    .Fetch(v => v.DescriptorClass)
                    .Fetch(v => v.SomeChild).ThenFetch(v => v.SomeGrandChild)
                    .Fetch(v => v.SomeChild).ThenFetch(v => v.DescriptorClass);

它工作正常但它在SomeChild上创建了一个带有两个连接的SQL查询。显然,我必须摆脱第二个Fetch(v =&gt; v.SomeChild),但我找不到如何做到这一点。 我试过了:

Session.Query<RootClass>().Where(/*some expressions here*/)
                    .Fetch(v => v.DescriptorClass)
                    .Fetch(v => v.SomeChild).ThenFetch(v => v.SomeGrandChild)
                    .ThenFetch(v => v.DescriptorClass); //<- wrong, tries to find DescriptorClass on SomeGranchild

Session.Query<RootClass>().Where(/*some expressions here*/)
                    .Fetch(v => v.DescriptorClass)
                    .Fetch(v => v.SomeChild).ThenFetch(v => v.SomeGrandChild)
                    .Fetch(v => v.DescriptorClass); //<- wrong, loads the same DescriptorClass of RootClass, not on SomeChild

如何告诉NHibernate在SomeChild上创建单个连接,然后获取SomeChild的SomeGrandChild和DescriptorClass?

1 个答案:

答案 0 :(得分:1)

对于这种类型的查询,切换到使用LINQ查询语法而不是lambdas,因为它可以提供更多控制,并且通常可以输出更高效,更清晰的SQL。

请查看下面的示例,并注意我如何使用别名“c”多次引用Customer实体。

var customers =
    (
        from c in session.Query<Customer>()
        from a in c.Addresses
        from pn in c.PhoneNumbers
        where c.Status == "Active"
                && a.City == "Dallas"
                && pn.AreaCode == "972"
        select c )
        .ToList();

这将导致以下SQL使用NHibernate:

SELECT
    customer0_.CustomerId as Customer1_135_0_,
    customer0_.Status as Customer1_135_1_
FROM
    Customer customer0_
INNER JOIN
    CustomerAddresses customeraddr1_
        ON customer0_.CustomerId=customeraddr1_.CustomerId
INNER JOIN
    CustomerPhoneNumbers customerphon2_
        ON customer0_.CustomerId=customerphon2_.CustomerId
WHERE
    customer0_.Status='Active' /* @p0 */
    AND customeraddr1_.City = 'Dallas' /* @p1 */
    AND customerphon2_.AreaCode = '972' /* @p2 */;
相关问题