【问题标题】:NHibernate Fetch / ThenFetch for joined siblingsNHibernate Fetch / ThenFetch 用于加入的兄弟姐妹
【发布时间】:2012-10-26 11:11:10
【问题描述】:

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

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 => 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 上创建单个连接,然后获取 SomeGrandChild 和 SomeChild 的 DescriptorClass?

【问题讨论】:

    标签: linq nhibernate join fetch


    【解决方案1】:

    对于这种类型的查询,请改用 LINQ 查询语法而不是 lambda,因为它可以提供更多控制权,并且通常会输出更高效、更简洁的 SQL。

    看看下面的示例,注意我是如何使用别名“c”多次引用客户实体的。

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

    这将导致以下使用 NHibernate 的 SQL:

    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 */;
    

    【讨论】:

    • 我得到:“类型推断在调用 'SelectMany' 时失败”。很可能是因为“from”正在发出“SelectMany”,但我有单个 SomeChild/DescriptorClass/SomeGrandChild 而不是它们的集合。
    猜你喜欢
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 2015-03-06
    相关资源
    最近更新 更多