简体   繁体   English

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

[英]NHibernate: Using createSQLQuery with one-to-one mapping causing extra queries

I am using the following code in my query 我在查询中使用以下代码

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);

It is using the following mapping: 它使用以下映射:

<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>

And here is a small sample of the SQL. 这是SQL的一个小样本。 The actual SQL is using features specific to Sql Server, but this simplified SQL demonstrates the same issue: 实际的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

Now my sql query returns all of the AllegroGoalContract instances along with the GoalDetail one-to-one association. 现在,我的sql查询返回所有AllegroGoalContract实例以及GoalDetail一对一关联。 Notice that the mapping for the one-to-one association has constrained="false" set indicating that there does not have to be a GoalDetail for every AllegroGoalContract. 请注意,一对一关联的映射已设置了constrained =“ false”,指示不必为每个AllegroGoalContract都有一个GoalDetail。

When I run this code, I see my query run but then I see nhibernate issue a separate query for every AllegroGoalContract instance where my query returned null for the GoalDetail. 当我运行此代码时,我看到我的查询正在运行,但是随后我看到nhibernate针对每个AllegroGoalContract实例发出一个单独的查询,其中我的查询为GoalDetail返回了null。 I suspect this is because nhibernate does not know if the null was returned because it was a lazy load or because it really does not exist. 我怀疑这是因为nhibernate不知道返回的null是因为它是延迟加载还是因为它实际上不存在。

So how can I tell nhibernate that the null from the CreateSQLQuery call for GoalDetails really means that they are not there so don't go and try and fetch them again. 因此,我怎么能告诉nhibernate,对TargetDetails的CreateSQLQuery调用中的null确实意味着它们不存在,所以不要去尝试再次获取它们。

The NHibernate mapping node - <one-to-one/> has an attribute called fetch, default value is - select which make a separate query for each adjunct entity. NHibernate映射节点- <one-to-one/>具有称为fetch的属性,默认值为-select,它为每个附加实体进行单独的查询。 If you want NHibernate to use SQL Join change to - 如果您希望NHibernate使用SQL Join,请更改为-

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM