【问题标题】:NHibernate: Check referenced entity only if it's not nullNHibernate:仅当它不为空时才检查引用的实体
【发布时间】:2015-06-04 22:54:57
【问题描述】:

表格:

  • 名称
    • 身份证
    • 修改日期
  • 名称链接
    • 身份证
    • nameid
    • 修改日期

NameLink 的映射:

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

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

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

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

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

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

【问题讨论】:

  • 您让 NHibernate 决定使用哪个 JOIN。它是内在的。您只需要 LEFT JOIN。调整您的 HQL 生成器,以确保您获得 LEFT JOIN。如果没有它,你可以使用任何类型的 IS NOT NULL...但是 INNER JOIN 无论如何都会过滤结果...

标签: nhibernate reference mapping nullable fluent


【解决方案1】:

一般来说,你需要使用的是左连接,这个语法会返回你所期望的

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 " 

【讨论】:

  • 感谢您的回答!是的,这肯定会奏效。但是,我期待我可以使用 Join 方法创建流畅的映射。我的 GET 查询将发送到 webapi。我们正在使用 OData 并手动创建 HQL 查询。所以我使用 OData 过滤器子句来添加 DateModified comarison。我已经编辑了我的问题。
  • 在这种情况下,映射不相关。因为映射的 relation 负责 JOIN 本身,但是如果使用 INNER 或 OUTER,QUERY(我们)可以影响。如果你手动创建 HQL 查询,你真的可以使用 LEFT join。这就是你真正应该做的。希望它有所帮助...我确实在查询中使用 LEFT JOIN 明确且几乎总是,因为它是非常标准的,我们的域模型包含可为空的引用...
  • 非常感谢您的回复!
  • 如果这有帮助的话,先生,太好了!享受惊人的 NHibernate ;)
猜你喜欢
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 2021-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多