NHibernate标准查询-如何链接逻辑运算符
我正在寻找一个示例,说明如何创建一个条件查询,该查询将生成与此类似(或具有同等效果)的SQL: 创建查询时,我有一个过滤器数据列表(填充“AND”后面的数据)以及一个额外的参数(填充上面的“some value”部分) 基本上,我的问题是在构建这种条件查询时如何链接and和ORs?表达式的API。和表达式。或只接受一个左右标准,而不是一个链 有人知道我在哪里可以找到这样的例子吗NHibernate标准查询-如何链接逻辑运算符,nhibernate,nhibernate-criteria,Nhibernate,Nhibernate Criteria,我正在寻找一个示例,说明如何创建一个条件查询,该查询将生成与此类似(或具有同等效果)的SQL: 创建查询时,我有一个过滤器数据列表(填充“AND”后面的数据)以及一个额外的参数(填充上面的“some value”部分) 基本上,我的问题是在构建这种条件查询时如何链接and和ORs?表达式的API。和表达式。或只接受一个左右标准,而不是一个链 有人知道我在哪里可以找到这样的例子吗 顺便说一句,x,y,z部分(在选择之后)目前是不相关的,因为我似乎可以用投影来完成它(还没有到那里)。没有逻辑运算符链
顺便说一句,x,y,z部分(在选择之后)目前是不相关的,因为我似乎可以用投影来完成它(还没有到那里)。没有逻辑运算符链接这样的东西。上述内容也可以写成
(tbl.b = '1' AND tbl.c = 'whatever1' AND tbl.d = 123) OR
((tbl.b = '2' AND tbl.c = 'whatever2' AND tbl.d = 456) OR
(tbl.b = '3' AND tbl.c = 'whatever3' AND tbl.d = 789))
也就是说,逻辑运算符总是有一个左参数和一个右参数
这就是说,位运算符对于限制
是重载的,因此以下操作有效:
criteria.Add(Restrictions.Eq("a", "some value") &
(Restrictions.Eq("b", 1) & Restrictions.Eq("c", "whatever1") |
(Restrictions.Eq("b", 2) & Restrictions.Eq("c", "whatever2"))))
//...etc...
通过CriteriaAPI,您可以使用连接(AND)和分离(OR)类。例如,请参见我最初的尝试似乎确实奏效了,因此我将公布我是如何做到的,以防引起任何人的兴趣。它看起来像这样:
public IEnumerable<Entity> Filter(FilterRequest filterRequest)
{
var criteria = session.CreateCriteria("Entity");
criteria.Add(
Expression.And(
CreateItemCriteria(filterRequest),
CreateKeysCriteria(filterRequest)));
return criteria.List<Entity>();
}
private static ICriterion CreateItemCriteria(FilterRequest filterRequest)
{
return Restrictions.Eq("a", filterRequest.ItemId);
}
private ICriterion CreateKeysCriteria(FilterRequest filterRequest)
{
ICriterion finalCriterion = null;
for (int i = 0; i < filterRequest.Keys.Count; i++)
{
var currentKeyCriterion = CreateKeyCriterion(filterRequest.Keys[i]);
finalCriterion = finalCriterion == null
? currentKeyCriterion
: Expression.Or(finalCriterion, currentKeyCriterion);
}
return finalCriterion;
}
private ICriterion CreateKeyCriterion(Key key)
{
return Expression.AllEq(new Dictionary<string, object>
{
{ "b", Key.b },
{ "c", Key.c },
{ "d", Key.d },
});
}
public IEnumerable筛选器(FilterRequest FilterRequest)
{
var-criteria=session.CreateCriteria(“实体”);
标准。添加(
表达。及(
CreateItemCriteria(filterRequest),
CreateKeysCriteria(filterRequest));
返回条件。List();
}
私有静态ICriterion CreateItemCriteria(FilterRequest FilterRequest)
{
返回限制.Eq(“a”,filterRequest.ItemId);
}
私有ICriterion CreateKeysCriteria(FilterRequest FilterRequest)
{
ICriterion finalCriterion=null;
对于(int i=0;i
虽然不是非常优雅,但它可以工作,结果SQL完全符合我的要求。那么在连接()之后,您可以添加任意数量的限制/表达式,它们将通过添加/或?还是我不明白这个例子?基本上是的。连词接受数字限制,并用逻辑and将其链接起来。析取也有许多限制,但用OR将它们链接起来。你也可以在连接词中包含析取,反之亦然。好吧,最后我没有尝试这个,因为我最初的尝试实际上奏效了,我不想改变它。但我会将此标记为答案,因为这似乎是一个优雅的解决方案(我希望它也能起作用)。我将分别发布我的答案。
public IEnumerable<Entity> Filter(FilterRequest filterRequest)
{
var criteria = session.CreateCriteria("Entity");
criteria.Add(
Expression.And(
CreateItemCriteria(filterRequest),
CreateKeysCriteria(filterRequest)));
return criteria.List<Entity>();
}
private static ICriterion CreateItemCriteria(FilterRequest filterRequest)
{
return Restrictions.Eq("a", filterRequest.ItemId);
}
private ICriterion CreateKeysCriteria(FilterRequest filterRequest)
{
ICriterion finalCriterion = null;
for (int i = 0; i < filterRequest.Keys.Count; i++)
{
var currentKeyCriterion = CreateKeyCriterion(filterRequest.Keys[i]);
finalCriterion = finalCriterion == null
? currentKeyCriterion
: Expression.Or(finalCriterion, currentKeyCriterion);
}
return finalCriterion;
}
private ICriterion CreateKeyCriterion(Key key)
{
return Expression.AllEq(new Dictionary<string, object>
{
{ "b", Key.b },
{ "c", Key.c },
{ "d", Key.d },
});
}