如果我想在查询中附加AND语句,我可以这样做:
query = query.Where(obj=>obj.Id == id);
if(name.HasValue)
query = query.Where(obj=>obj.Name == name);
它会给我:
query.Where(obj=>obj.Id == id && obj.Name == name)
如何附加导致以下内容的OR语句:
query.Where(obj=>obj.Id == id || obj.Name == name)
答案 0 :(得分:6)
你不能本地做。但是,您可以在运行之前使用PredicateBuilder撰写查询,并且它支持OR。
var predicate = PredicateBuilder.False<Product>();
predicate = predicate.Or (obj=>obj.Id == id);
if(name.HasValue) predicate = predicate.Or (obj=>obj.Name == name);
return query.Where(predicate);
答案 1 :(得分:3)
如果我没有遗漏某些内容,那就是这样:
query.Where(obj=>obj.Id == id || (obj.Name == name && name.HasValue))
您可能想要阅读这个问题(我的问题......)并回答更复杂的情况:
How to filter IEnumerable based on an entity input parameter
答案 2 :(得分:0)
我只是把它构建成一个条件:
if (name.HasValue)
query = query.Where(obj=>obj.Id == id && obj.Name == name);
else
query = query.Where(obj=>obj.Id == id);
答案 3 :(得分:0)
我会使用gdoron的解决方案,但如果对于更大的查询集似乎不太实际,那么包含set操作的稍微复杂的解决方案可能对您有所帮助:
var queryById = query.Where(obj => obj.Id == id);
var queryByName = query.Where(obj => obj.Name == name);
query = queryById.Union(queryByName);
如果原始查询包含重复项,则会变得更加困难。
另一种方法可能是使用Expression
来制定您的查询。您可以在执行之前修改表达式树,以便可以向Where
子树添加更多条件。这是一个整批的工作,对于99.9%(粗略估计:)的案例来说是一种过度杀伤。
答案 4 :(得分:0)
部分问题在于您过度编写原始查询。你的OR操作相当于:
subquery1 = query.Where(obj=>obj.Id == id);
subquery2 = query.Where(obj=>obj.Name == name);
query = subquery1.Concat(subquery2).Distinct();
正如你所看到的那样,这也变得相当笨拙,但是如果你打算做这个形式,那么你必须保持原始序列,这样你就可以得到处理方程的左右两边然后你需要确保重复删除。
而不是所有这些,我会尝试使用lambdas动态构建条件语句,例如。
我实际上并没有这样做,但是这样的事情应该有效。
var cond = obj=>obj.Id == id;
...
// need an or
cond = obj=>cond(obj) || obj.Name == name;
query = query.Where(obj=>cond(obj));
希望这会给你一个想法。