2009-08-26 16 views
12

这可能是显而易见的,但我一直对我的头撞了几个小时,不知道我要去哪里错了。NHibernate分离导致AND查询,而不是OR

我想运行一小段代码来测试向NHibernate查询添加OR条件。这是我的代码:

using (ISession session = NHibernateHelper.OpenSession()) 
{ 
    ICriteria criteria = session.CreateCriteria<TestObject>(); 

    int[] ids = {1, 2, 3}; 
    foreach (int id in ids) 
    { 
     ICriterion criterion = Restrictions.Eq("Id", id); 
     criteria.Add(Restrictions.Disjunction().Add(criterion)); 
    } 

    IList<TestObject> items = criteria.List<TestObject>(); 
    return items; 
} 

这只是简单的东西,我会希望返回与标识1-3的所有测试对象。但是,当我运行代码时,生成的查询是查找ID = 1 AND ID = 2 AND ID = 3的对象。毫不奇怪,这不会返回任何内容。

映射的设置正确(我可以添加/编辑/删除/列出所有对象),并且存在具有这些ID的对象。

我在做什么明显错误?任何使用Disjunction的例子都在网上看过,似乎都是这样用的。我只是不明白为什么它继续使用AND。

谢谢。

回答

16

你的问题在于你每次创建一个新的分离(循环)。你需要做的是:

int[] ids = {1, 2, 3}; 
ICriterion disjunction = Restrictions.Disjunction(); 
foreach (int id in ids) 
{ 
    ICriterion criterion = Restrictions.Eq("Id", id) 
    disjunction.Add(criterion); 
} 
criteria.Add(disjunction); 

的语法可能有点不对 - 我是一个Hibernate的人,而不是.NET :-)

为了澄清,原来的代码会产生类似的信息(在伪代码中):

WHERE (OR(ID=1)) AND (OR(ID=2)) AND (OR(ID=3)) 

既然没有什么要“或”,分离被默默地省略。基于ChssPly76的回答

+1

魔术,得到成功的治疗。当我看着你的代码时是有意义的 - 我从来没有想过它会将单个OR“联系在一起”。 对代码的唯一小改动是创建析取如下: Junction disjunction = Restrictions.Disjunction(); (ICriterion没有'添加')。 谢谢! – 2009-08-26 18:40:49

5

更新代码:

using (ISession session = NHibernateHelper.OpenSession()) 
{ 
    ICriteria criteria = session.CreateCriteria<TestObject>(); 
    Junction disjunction = Restrictions.Disjunction(); 

    int[] ids = {1, 2, 3}; 
    foreach (int id in ids) 
    { 
     ICriterion criterion = Restrictions.Eq("Id", id); 
     disjunction.Add(criterion); 
    } 
    criteria.Add(disjunction); 


    IList<TestObject> items = criteria.List<TestObject>(); 
    return items; 
}