C# 如何在LINQ中建立动态OR查询?
我正在尝试用link动态创建一个where子句。 现在,创建类似于C# 如何在LINQ中建立动态OR查询?,c#,linq,C#,Linq,我正在尝试用link动态创建一个where子句。 现在,创建类似于选择产品的东西,其中x=123、y=349和w=948是没有问题的。我只是在添加额外的Where过滤器。 products=products.Where(product=>product.Property==123) 但现在我有一个未知数量的值,应该用OR运算符测试。SQL应该类似于选择产品,其中x=123或x=499或x=998。。和n个或更多的建立一个数字列表以进行检查,并执行以下操作: var idsToCheck = ne
选择产品的东西,其中x=123、y=349和w=948
是没有问题的。我只是在添加额外的Where过滤器。
products=products.Where(product=>product.Property==123)代码>
但现在我有一个未知数量的值,应该用OR运算符测试。SQL应该类似于选择产品,其中x=123或x=499或x=998。。和n个或更多的
建立一个数字列表以进行检查,并执行以下操作:
var idsToCheck = new List<int>{123, 789, 654}; //Build from dynamic list
products = products.Where(x => idsToCheck.Contains(x.Id));
var idsToCheck=新列表{123789654}//从动态列表生成
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));
var idsToCheck=新列表{123789654}//从动态列表生成
products=products.Where(x=>idsToCheck.Contains(x.Id));
var-propertyToCheck=新列表{123789654}//从动态列表生成
products=products.Where(x=>propertyToCheck.Contains(x.Property));
var numberToCheck=新列表{123789654};
products=products.Where(x=>numberToCheck.Contains(x.Number));
如果要检查的值已作为可枚举项传入,则无需构建xxxToCheck集合。您只需对原始文件执行
.Contains
,您可以在列表中使用Contains,也可以使用如下等式:
products.Where(product => (product.Property == 123) || (product.Property == 499) || (product.Property == 998));
如果您想从多个where子句组合OR查询,那么您确实需要在where子句中组合谓词。毕竟,链接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;
Func w1=p=>p.x==123;
Func w2=p=>p.y==349;
Func w3=p=>p.w==948;
Func w4=p=>p.Property==123;
Func w5=p=>p.x==499;
Func w6=p=>p.x==998;
您可以定义以下扩展方法来访问或访问它们:
public static Func<T, bool> Or<T>(this Func<T, bool> @this, Func<T, bool> that)
{
return t => @this(t) || that(t);
}
public static Func Or(this Func@this,Func that)
{
返回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));
var products1=产品,其中(w1.或(w5).或(w6));
var products2=产品。其中(
((Func)(p=>p.x==123))
.或(p=>p.y==349)
或(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));
}
公共静态函数或(this IEnumerable@this)
{
返回@this.Aggregate((Func)(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());
var谓词=新列表()
{
p=>p.x==123,
p=>p.w==948,
p=>p.属性==123,
p=>p.x==998,
};
var products3=products.Where(谓词或());
如果您是针对IQueryable
提供程序编写的,那么您需要使用Expression
而不仅仅是Func
然后您需要这些扩展方法:
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));
}
公共静态表达式或(
这个表达式@this,
表达(即)
{
变量参数=
表示
.参数(类型为(T),“T”);
变位体=
表示
.或(
表示
.Invoke(@this,param),
表示
.调用(that,param));
回来
表示
.Lambda(主体,参数);
}
公共静态表达式或(
this(可数@this)
{
返回@this.Aggregate((表达式)(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());
var-predictESX=新列表()
{
p=>p.x==123,
p=>p.w==948,
p=>p.属性==123,
p=>p.x==998,
};
var products3X=products.Where(predictESX.Or());
这就是你要找的吗?我希望上面查询的SQL是
SELECT Product WHERE x IN(123,499,998)
是的,你是对的,SQL描述得更好一些!