你能过滤 nhibernate 子集合吗?

Can you filter nhibernate sub collection?

我有以下 nHibernate 查询,它非常适合我拉取实体并渴望获取其子集合。

var contactInfo = session.QueryOver<PeopleInfo>()
                         .Fetch(x => x.Addresses).Eager
                         .Fetch(x => x.EmailAddresses).Eager
                         .Fetch(x => x.PhoneNumbers).Eager
                         .Where(x => x.Id == contactInfoId)
                         .SingleOrDefault();

现在,假设在 Addresses 中有一个名为 Active 的字段, 有没有办法在一次调用中 return 所有活动地址?

我可以事后过滤掉,我只是想知道是否有 一种通过查询完成的方法。

谢谢!

是的,您可以这样做,但您需要在 QueryOver 查询中包含一些联接。

在幕后,.Fetch 正在生成一堆 LEFT JOIN 以带回 PeopleInfo 的完整列表,而不排除没有任何关联集合的人你正在急切地获取。

您可以通过自己执行左联接来覆盖执行联接的方式。

例如,如果您想要获取所有 PeopleInfo,并且只获取 Active 的地址,您可以执行以下操作:

Address addressAlias;

var addressRestriction = Restrictions.Where(() => address.Active);

session.QueryOver<PeopleInfo>()
    .Left.JoinQueryOver(
        pi => pi.Addresses, () => addressAlias, addressRestriction)
    .Fetch(x => x.Addresses).Eager
    .Fetch(x => x.EmailAddresses).Eager
    .Fetch(x => x.PhoneNumbers).Eager
    .Where(x => x.Id == contactInfoId)
    .SingleOrDefault();

现在,由于您 JOINAddress 上选择了整个 PeopleInfo 实体,您实际上不需要使用 .Fetch 来拉返回所有 Address 字段。

session.QueryOver<PeopleInfo>()
    .Left.JoinQueryOver(
        x => x.Addresses, () => addressAlias, addressRestriction)
    .Fetch(x => x.EmailAddresses).Eager
    .Fetch(x => x.PhoneNumbers).Eager
    .Where(x => x.Id == contactInfoId)
    .SingleOrDefault();

Address 列包含在 SELECT 子句中,因为您已加入 Address 并选择了整个 PeopleInfo class。

它们都生成相同的 SQL,但您应该在分析器中进行验证。它应该看起来像这样:

SELECT this_.*         -- All PeopleInfo columns
       addressali1_.*, -- All Address columns 
       emailaddre4_.*  -- All email address columns
FROM   PeopleInfo this_ 
       LEFT OUTER JOIN address addressali1_ 
                    ON this_.id = addressali1_.personid 
                       AND ( addressali1_.active = 1) 
       LEFT OUTER JOIN emailaddress emailaddre4_ 
                    ON this_.id = emailaddre4_.personid 
WHERE  this_.id = <your id>