【问题标题】:Creating a nested OR statement using NHibernate Criteria API使用 NHibernate Criteria API 创建嵌套 OR 语句
【发布时间】:2012-02-15 19:28:35
【问题描述】:

所以我喜欢学习有关 NHibernate 的新东西,因为它确实非常灵活,并且让我的生活变得轻松,除了我现在卡在哪里;)。到目前为止我还没有做过很复杂的查询,这个也不复杂,但是我觉得最常用的方法和对象类型都覆盖不了这个问题。

这是我要查询的内容:

SELECT _Table1.UserID, _Table1.ColorID, _Table1.AppID FROM _Table1
INNER JOIN _Table2 ON _Table2.AppID = _Table1.AppID 
WHERE _Table1.ColorID= @param0
AND (
      _Table2.WindowID = @param1 OR
      _Table2.WindowID = @param2 OR
      _Table2.WindowID = @param3 OR
      ................ = @param(N - 1)
    ) 

这是我使用标准 API 的结果

private IList<Table1Entity> FetchListByWindowId(int colorID, List<int> listOfWindowIDs)
{

    var list = CurrentSession.CreateCriteria<Table1Entity>()
                 .Add(Restrictions.Eq("ColorID", colorID))
                 .CreateCriteria("Table2EntityList");

    foreach (var item in listOfWindowIDs)
    {
        list.GetCriteriaByPath("Table2EntityList")
            .Add(Restrictions.Eq("WindowID", Int32.Parse(item)
    }
}

表 1 的映射包括 4 个属性 UserID、ColorID、AppID 和 HasMany 到 Table2 实体。

HasMany<Table2Entity>(x => x.Table2EntityList)
     .KeyColumns.Add("AppID")
     .Not.LazyLoad()
     .Inverse()
     .Cascade.None();

从我一整天都在寻找解决方案开始,我认为没有一种简单的方法可以明确地说“制作这些表达式 OR”(是的,我已经看过 Expression.OR,这不是我想要的想要)。

NHibernate 给我的查询正是我想要的,只是我需要用“ORs”替换一些“ANDs”

谢谢,如果这变得非常微不足道,我们深表歉意。我也想为我的代码含糊不清道歉,但我处理的是敏感数据。所以所有的变量名和方法名之类的都要调整一下。

编辑: NHibernate 目前给我的查询:

SELECT _Table1.UserID, _Table1.ColorID, _Table1.AppID FROM _Table1
INNER JOIN _Table2 ON _Table2.AppID = _Table1.AppID 
WHERE _Table1.ColorID= @param0
AND (
      _Table2.WindowID = @param1
      AND _Table2.WindowID = @param2 
      AND _Table2.WindowID = @param3
      AND ................ = @param(N - 1)
    ) 

【问题讨论】:

  • 不,我看过了,我能得到的只是表达。或者想要两个东西相互比较。我相信我想要的是限制一个字段等于一组数据中的一个项目。我不做比较。但我没有花时间看 Disjunction。那我去看看。
  • 我认为 Disjunction() 是朝着正确道路迈出的一步,因为我有一组项目,我想说 A 或 B 或 C 之类的东西......但我添加了一个 Expressions.Disjunction( ),我仍然得到相同的查询。

标签: c# sql-server-2008 nhibernate nested criteria-api


【解决方案1】:

类似:

var disjunction = new Disjunction()
    .Add(Restriction.Eq("WindowID", item1))
    .Add(Restriction.Eq("WindowID", item2))
    .Add(Restriction.Eq("WindowID", item3));
// Or use a loop if you like...

var list = CurrentSession.CreateCriteria<Table1Entity>()
    .Add(Restrictions.Eq("ColorID", colorID))
    .CreateCriteria("Table2EntityList")
    .Add(disjunction);

【讨论】:

  • 是的,这行得通。太棒了,我真的很感谢你的帮助。我所做的是创建了一个析取,并在我的循环中添加了限制,然后我列出了我的列表(就像你的回答一样)。查询结果为“SELECT * FROM TABLE1 INNER JOIN TABLE2 ON ID = ID WHERE COLOR = P0 AND (Window = P1 OR P2....PN)”感谢您的快速回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
  • 2012-09-26
  • 2012-10-15
相关资源
最近更新 更多