我有以下(简化的)实体层次结构:
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?
答案 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 */;