我正在寻找一个如何创建条件查询的示例,该查询会导致SQL与此类似(或具有等效效果):
SELECT x, y, z
FROM SomeTable tbl
WHERE tbl.a = 'some value'
AND (
(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)
)
创建查询时,我有一个过滤数据列表(填充“AND”之后的数据)以及一个额外的参数(填充上面的“某个值”部分)。
基本上我的问题是在构建这种标准查询时如何链接AND和OR? Expression.And和Expression.Or的API只接受单个左右标准,而不是链。
有谁知道我可以在哪里找到一个例子?
顺便说一下,x,y,z部分(在SELECT之后)目前无关紧要,因为我似乎可以用投影来完成它(还没有到达那里)。答案 0 :(得分:1)
没有逻辑运算符链接这样的东西。以上也可以写成
(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))
也就是说,逻辑运算符始终具有左参数和右参数。
也就是说,Restriction
的位运算符过载,因此以下工作原理:
criteria.Add(Restrictions.Eq("a", "some value") &
(Restrictions.Eq("b", 1) & Restrictions.Eq("c", "whatever1") |
(Restrictions.Eq("b", 2) & Restrictions.Eq("c", "whatever2"))))
//...etc...
答案 1 :(得分:1)
使用条件API,您可以使用连词(AND)和Disjunction(OR)类。有关示例,请参阅this stackoverflow thread
答案 2 :(得分:0)
好吧,看起来我最初的尝试确实有效,所以我会发布我是如何做到的,以防任何人感兴趣。它看起来像这样:
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 },
});
}
不是非常优雅,但它有效,结果SQL完全符合我的要求。