在NHibernate中,使用Disjunction可以得到双重结果
我正在尝试使用DetachedCriteria进行选择,我想在运行时添加OR分隔的几个条件。
如果我使用:
Restrictions.Or( cond1, Restrictions.Or(cond2, Restrictions.Or(cond3, cond4)) )
我得到了我想要的结果。
但如果我像这样使用Disjunction:
var disjunction = Restrictions.Disjunction(); disjunction.Add(cond1); disjunction.Add(cond2); disjunction.Add(cond3); disjunction.Add(cond4);
我有cond1和cond2的实体对他们来说是真的,在结果我得到它们两次(在列表结果中相同的实体被返回两次)。
我不想使用QueryOver,因为我正在尝试使用QueryOver来完成一些难以实现的事情(我正在尝试做的最终结果是从filter的json获取sql查询)。
什么导致分离返回双打? 有没有办法在最后添加DISTINCT? 我做错了,我不应该在同一张桌子上使用析取不同的条件吗?
更新:
对于DISTINCT部分:
criteria.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer());
要么
Projections.Distinct(Projections.Id())
真正的解决方案如RadimKöhler所述 – 正确使用子查询。
一个小借口:问题没有提供任何映射,也缺少查询……所以人们只能猜出问题是什么。 但是,我们试着提供一些解释
为什么收到不明显?
我们有两个表(在问题下面的一条评论中给出)
家长:
ParentId | Name 1 | Parent_A 2 | Parent_B
儿童:
ChildId | Color | ParentId 1 | green | 1 2 | grey | 1 3 | gold | 1 4 | green | 2
如果我们将在纯SQL中创建简单选择,请执行此操作
SELECT p.ParentId, p.Name FROM Parent AS p INNER JOIN Child AS c ON p.ParentId = c.ParentId WHERE c.Color = 'green' OR c.Color = 'grey' OR c.Color = 'gold'
这个查询的结果是什么?
1 | Parent_A 1 | Parent_A 1 | Parent_A 2 | Parent_B
如果我们将其转换为类似的标准:
var sesion = ... // get session var parent = sesion.CreateCriteria(); var children = parent.CreateCriteria("Children"); // restrict the children children.Add(Restrictions.Disjunction() .Add(Restrictions.Eq("Color", "green")) .Add(Restrictions.Eq("Color", "grey")) .Add(Restrictions.Eq("Color", "gold")) ); var list = parent .SetMaxResults(10) // does not matter in our example, but ... it should be used always .List ();
这是Criteria C#代码,它将导致多个Parent (因为事实上,将生成如上所述的相同SQL)
正如我们所看到的,问题肯定不在 NHiberante方面。 真! NHibernate不仅是无辜的,而且还在做所需的事情。
解
解决方案在子选择中
在SQL中它将是这样的
SELECT p.ParentId, p.Name FROM Parent AS p WHERE p.ParentId IN ( SELECT c.ParentId FROM Child AS c WHERE c.ParentId = p.ParentId AND c.Color = 'green' OR c.Color = 'grey' OR c.Color = 'gold' )
这将为我们提供我们最想要的结果:
1 | Parent_A 2 | Parent_B
如何在NHibernate中做到这一点?
var sesion = ... // get session var parent = sesion.CreateCriteria(); //var children = parent.CreateCriteria("Children"); var children = DetachedCriteria.For(typeof(Child)); // restrict the children children.Add(Restrictions.Disjunction() .Add(Restrictions.Eq("Color", "green")) .Add(Restrictions.Eq("Color", "grey")) .Add(Restrictions.Eq("Color", "gold")) ); // ad SELECT into this sub-select children.SetProjection( Projections.Property("ParentId")); // filter the parent parent .Add(Subqueries.PropertyIn("ParentId", children)); var list = parent .SetMaxResults(10) // does not matter in our example, but ... it should be used always .List ();
现在,我们确实有sub-select( DetachedCriteria
和Subqueries
NHibernatefunction)而且没有更多的DUPLICATES!
上述就是C#学习教程:在NHibernate中,使用Disjunction可以得到双重结果分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/936537.html