NHibernate:仅当引用的实体不为空时才检查它

NHibernate: Check referenced entity only if it's not null

表格:

NameLink 的映射:

Id(p => p.Id, "id").GeneratedBy.GuidComb();
Map(p => p.DateModified, "datemodified");
References<Name>(p => p.Name, "nameid");

名称条目可能已从 table 中删除。在我的 hql 查询中,我试图检查 Name 是否不为 null,并且仅当它为 null 时 - 检查它的 datemodified。如果 Name 为空,我将仅检查 NameLink 的修改日期:

where ($it.Name is not null AND $it.Name.DateModified > 'xxx') OR ($it.DateModified > 'xxx')

如果名称条目被删除,我不会得到任何结果,但我应该这样做。我截获了SQL。 我看到在 WHERE 子句中,第一个检查是 "namelink.nameid = name.id"。我相信这是因为 Reference<> 关系。

有人可以帮我修改映射吗?

编辑: 我的 GET 查询转到我们正在将其转换为 HQL 的 WebAPI。此查询转到 BaseController,因此我只能使用 OData 可能性修改查询结果,因为代码对于所有其他实体类型都是通用的。我得到了这种 HQL 查询 from NameExternalLink $it where (($it.Name.DateModifiedUtc > '2015-03-31 11:29:45' OR $it.Name.DateCreatedUtc > '2015-03-31 11:29:45')) or ($it.DateModifiedUtc > '2015-03-31 11:29:45' OR $it.DateCreatedUtc > '2015-03-31 11:29:45') 但是如果相应的行被删除,$it.Name 可能为空。如果存在相应的名称,则查询工作正常,但如果删除了该行,则会跳过该行。我认为它被跳过了,因为名称是由 "References" 关系映射的,当 hql 转换为 sql 时,它试图通过比较 NameLink.nameid = Name.id 来获取名称,但名称为空。

一般来说,您需要使用的是 left join,此语法将 return 您所期望的

session
    .CreateQuery("select nl " +
                 " FROM NameLink nl " +
                 "  LEFT JOIN nl.Name n " +
                 " WHERE  n.DateModified > :xxx " + 
                 "    OR nl.DateModified > :xxx " 
    )
    .SetParameter("xxx", someDate)
    // some paging
    .SetMaxResults(2)
    // result just NameLink
    .List<NameLink>();

但实际上,这个 WHERE 也可以工作

" WHERE COALESCE(n.DateModified , nl.DateModified ) > :xxx "