我正在尝试使用link动态创建where子句。
现在,创建像SELECT Product WHERE x = 123 AND y = 349 AND w = 948
这样的东西没问题。我只是添加额外的Where过滤器。
products = products.Where(product => product.Property == 123);
但是现在我有一个未知数量的值,应该使用OR运算符进行测试。 SQL应该像SELECT Product WHERE x = 123 OR x = 499 OR x = 998 .. and n more OR's
答案 0 :(得分:3)
构建要检查的数字列表,并执行以下操作:
var idsToCheck = new List<int>{123, 789, 654}; //Build from dynamic list
products = products.Where(x => idsToCheck.Contains(x.Id));
如果需要,上面的内容可以复制为v和w
var idsToCheck = new List<int>{123, 789, 654}; //Build from dynamic list
products = products.Where(x => idsToCheck.Contains(x.Id));
var propertyToCheck = new List<int>{123, 789, 654};//Build from dynamic list
products = products.Where(x => propertyToCheck.Contains(x.Property));
var numberToCheck = new List<int>{123, 789, 654};
products = products.Where(x => numberToCheck.Contains(x.Number));
如果要检查的值已经作为枚举传入,那么您不需要构建xxxToCheck集合。您只需针对原件执行.Contains
答案 1 :(得分:0)
您可以在列表中使用contains,或者只使用如下公式:
products.Where(product => (product.Property == 123) || (product.Property == 499) || (product.Property == 998));
答案 2 :(得分:0)
如果要从多个where子句组成OR查询,则确实需要在where子句中组合谓词。毕竟,链接的条款将是AND。
所以,如果您有以下谓词:
Func<Product, bool> w1 = p => p.x == 123;
Func<Product, bool> w2 = p => p.y == 349;
Func<Product, bool> w3 = p => p.w == 948;
Func<Product, bool> w4 = p => p.Property == 123;
Func<Product, bool> w5 = p => p.x == 499;
Func<Product, bool> w6 = p => p.x == 998;
您可以将以下扩展方法定义为OR:
public static Func<T, bool> Or<T>(this Func<T, bool> @this, Func<T, bool> that)
{
return t => @this(t) || that(t);
}
现在你可以写:
var products1 = products.Where(w1.Or(w5).Or(w6));
var products2 = products.Where(
((Func<Product, bool>)(p => p.x == 123))
.Or(p => p.y == 349)
.Or(p => p.Property == 123));
如果您想使用子句列表,请添加此扩展方法:
public static Func<T, bool> Or<T>(this IEnumerable<Func<T, bool>> @this)
{
return @this.Aggregate((Func<T, bool>)(t => true), (a, t) => a.Or(t));
}
现在你可以写:
var predicates = new List<Func<Product, bool>>()
{
p => p.x == 123,
p => p.w == 948,
p => p.Property == 123,
p => p.x == 998,
};
var products3 = products.Where(predicates.Or());
如果您是针对IQueryable<T>
提供商撰写的,那么您需要使用Expression<Func<Product, bool>>
而不仅仅是Func<Product, bool>
。
然后你需要这些扩展方法:
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> @this,
Expression<Func<T, bool>> that)
{
var param =
Expression
.Parameter(typeof(T), "t");
var body =
Expression
.Or(
Expression
.Invoke(@this, param),
Expression
.Invoke(that, param));
return
Expression
.Lambda<Func<T, bool>>(body, param);
}
public static Expression<Func<T, bool>> Or<T>(
this IEnumerable<Expression<Func<T, bool>>> @this)
{
return @this.Aggregate((Expression<Func<T, bool>>)(t => true), (a, t) => a.Or(t));
}
调用代码仍然有效:
var predicatesX = new List<Expression<Func<Product, bool>>>()
{
p => p.x == 123,
p => p.w == 948,
p => p.Property == 123,
p => p.x == 998,
};
var products3X = products.Where(predicatesX.Or());
这是你在找什么?