NHibernate:使用createSQLQuery与一对一的映射导致额外的查询

本文关键字:查询 映射 NHibernate 使用 createSQLQuery 一对一 | 更新日期: 2023-09-27 17:54:02

我在查询中使用以下代码

var query = session.CreateSQLQuery(sqlQuery)
    .AddEntity("g", typeof(AllegroGoalContract))
    .AddJoin("gd", "g.GoalDetail")
    .SetInt32("max", max.Value)
    .SetGuid("callerId", ServerContext.Current.TeamMemberUniqueId)
    .SetInt32("ver", lastChange);

使用以下映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="Methodology" >
    <class name="SixDisciplines.AllegroGoalContract, SixDisciplines" table="Goal" lazy="false">
        .
        .
        <one-to-one name="GoalDetail" class="SixDisciplines.AllegroGoalDetailContract, SixDisciplines" constrained="false"/>
        .
        .
    </class>
</hibernate-mapping>

这里是一个SQL的小样本。实际的SQL使用了SQL Server特有的特性,但是这个简化的SQL演示了同样的问题:

SELECT
g.UniqueId AS {g.UniqueId},
g.Description AS {g.Description},
g.StatusId AS {g.Status},
gd.UniqueId AS {gd.UniqueId},
gd.ActualEnd AS {gd.ActualEnd}
FROM Methodology.Goal g
LEFT JOIN Methodology.GoalDetail gd ON g.UniqueId = gd.UniqueId

现在我的sql查询返回所有AllegroGoalContract实例以及GoalDetail一对一的关联。注意,一对一关联的映射设置了constrained="false",这表明不需要每个AllegroGoalContract都有一个GoalDetail。

当我运行这段代码时,我看到我的查询运行,但随后我看到nhibernate为每个AllegroGoalContract实例发出一个单独的查询,其中我的查询为GoalDetail返回null。我怀疑这是因为nhibernate不知道返回null是因为它是延迟加载还是因为它真的不存在。

那么我怎么能告诉nhibernate从CreateSQLQuery调用的目标细节的空真的意味着他们不存在,所以不要去,并试图再次取回他们

NHibernate:使用createSQLQuery与一对一的映射导致额外的查询

NHibernate映射节点- <one-to-one/>有一个名为fetch的属性,默认值为- select,它对每个附加实体进行单独的查询。如果你想让NHibernate使用SQL Join,修改为-

<one-to-one name="GoalDetail" class="SixDisciplines.AllegroGoalDetailContract, SixDisciplines" constrained="false" fetch="join" outer-join="true"/>