4

如果我想将 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)
4

5 回答 5

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);
于 2012-11-19T21:04:30.360 回答
3

如果我没有遗漏什么,那就简单地说:

query.Where(obj=>obj.Id == id || (obj.Name == name && name.HasValue))

您可能想阅读这个问题(我的问题......)并回答更复杂的场景:
How to filter IEnumerable based on an entity input parameter

于 2012-11-19T21:04:25.223 回答
0

我只是把它构建成一个单一的条件:

if (name.HasValue)
    query = query.Where(obj=>obj.Id == id && obj.Name == name);
else
    query = query.Where(obj=>obj.Id == id);
于 2012-11-19T21:04:45.147 回答
0

我会使用 gdoron 的解决方案,但如果对于较大的查询集似乎不切实际,包含集合操作的稍微复杂的解决方案可能会对您有所帮助:

var queryById = query.Where(obj => obj.Id == id);
var queryByName = query.Where(obj => obj.Name == name);
query = queryById.Union(queryByName);

如果您的原始查询包含重复项,则会变得更加困难。

另一种方法可能是Expression用来制定您的查询。您可以在执行前修改表达式树,这样您就可以向Where子树添加更多条件。这是大量的工作,而且对于 99.9%(粗略估计 :))的案例来说,这太过分了。

于 2012-11-19T21:30:13.410 回答
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));

希望这能给你一个想法。

于 2012-11-19T21:40:47.200 回答