为什么这两个NHibernate查询产生不同的结果?

时间:2011-06-01 18:16:04

标签: nhibernate criteria linq-to-nhibernate

这是一个M:N关系,集合在NHibernate中映射为Set。

我们之前使用的标准查询“有效”,但它没有正确填充技能集合,因为只有第一个/寻找技能被降低,即使员工有多种技能。

我将其更改为LINQ查询,它修复了问题,正确获取了该员工的所有技能。

Dim sId = 1 ' Just to have one for example
Dim lstEmployees = Session.CreateCriteria(Of Employee)() _
                    .CreateAlias("Skills", "s", NHibernate.SqlCommand.JoinType.LeftOuterJoin) _
                    .Add(Expression.Or(Expression.Eq("PrimarySkillId", sId),
                                       Expression.Eq("s.Id", sId))) _
                    .SetResultTransformer(New DistinctRootEntityResultTransformer()) _
                    .List(Of Employee)()

' Returns correct employees but only their first skill in the Skills collection, even if they have more than one

Dim lstEmployees = (From e In Session.Query(Of Employee)()
                  Where e.PrimarySkillId =sId OrElse e.Skills.Any(Function(s) s.Id = sId)
                  Select e Distinct).Fetch(Function(e) e.Skills).ToList()

' Returns correct employees and their Skills collection contains all of their skills

有没有人理解两个看似相同的查询有什么不同?

1 个答案:

答案 0 :(得分:0)

关闭,第一个查询在检索所有行后执行明显分离,而第二个查询实际执行select distinct ...。可能发生的事情是它只用一个技能检索来保护员工模型

要使第一个查询实际执行select distinct ...,您需要使用投影。

这样的东西
Session.CreateCriteria(Of Employee)() _
       .CreateAlias("Skills", "s", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
       .Add(Expression.Or(Expression.Eq("PrimarySkillId", sId),
                          Expression.Eq("s.Id", sId))) _
       .SetProjection(Projections.Distinct("Id")) _
       .SetFetchMode("s", FetchMode.Eager)

可能会奏效。或者,您可以尝试使用DistinctRootEntityResultTransformer设置获取模式

Session.CreateCriteria(Of Employee)() _
       .CreateAlias("Skills", "s", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
       .Add(Expression.Or(Expression.Eq("PrimarySkillId", sId),
                          Expression.Eq("s.Id", sId))) _
       .SetResultTransformer(Transformers.DistinctRootEntityResultTransformer) _
       .SetFetchMode("s", FetchMode.Eager)