这是一个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
有没有人理解两个看似相同的查询有什么不同?
答案 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)