问题描述
假设我们需要应用几个条件来从名为事物"(未知数量和性质)的表中进行选择
Let's say we need to apply several conditions to select from a table called "Things" (unknown count and nature)
如果条件已知,我们可以写
if conditions are known, we can write
db.Things.Where(t=>foo1 && foo2 || foo3);
但是如果我们必须以编程方式构建 Where 条件,我可以想象我们如何应用 AND 条件
but if we have to build that Where condition programatically, I can imagine how can we apply ANDed conditions
IQuerable DesiredThings = db.Things.AsQuerable();
foreach (Condition c in AndedConditions)
DesiredThings = DesiredThings.Where(t => GenerateCondition(c,t));
ORed 条件怎么样?注意:我们不想执行联合、唯一或任何其他昂贵的操作,希望生成查询就像我们临时编写的一样
What about ORed conditions ? Note: we don't want to perform union, unique, or any other costly operations, it's desired that a query is generated as if we write it ad-hock
提前致谢.
PredicateBuilder: 动态组合表达式谓词
推荐答案
您可以使用带有静态方法的 Expression 类来实现它的运行时.
You could use the Expression class with static methods to do it run time.
以下代码用于创建一个委托,该委托采用一个名为 int 类型的值的参数.它从底部到顶部读取,因此有问题的行是:
The below code is ment to create a delegate taking one argument called value of type int . It reads from buttom to top so the line in question is:
var method = LambdaExpression.Lambda(orExp, Expression.Parameter(typeof(int), "value"));
方法体将参数值与对新创建的 foo 类型对象的方法 Bar 的调用进行比较
the body of the method compares the value of the parameter to a call to method Bar of a newly created object of type foo
var exp2 = Expression.Equal(Expression.Parameter(typeof(int), "value"), Expression.Property(Expression.New(typeof(Foo).GetConstructor(new Type[] { })), "Bar"));
然后它会创建一个类似的表达式和或它们
It then creates a similar expression and or's them
var orExp = Expression.OrElse(exp1, exp2);
最后一件事是调用编译.该调用会生成一个委托,可在您的 where 方法调用中使用.
final thing is the call to compile. That call generates a delegate that can be used in your where method call.
希望它有助于我不是 100% 确定表达式从参数中获取值
hope it helps tho Im not 100% sure on the expression to get the value from a parameter
var exp1 = Expression.Equal(Expression.Parameter(typeof(int),"value"), Expression.Property(Expression.New(typeof(Bar).GetConstructor(new Type[] { })), "Foo"));
var exp2 = Expression.Equal(Expression.Parameter(typeof(int), "value"), Expression.Property(Expression.New(typeof(Foo).GetConstructor(new Type[] { })), "Bar"));
var orExp = Expression.OrElse(exp1, exp2);
var method = LambdaExpression.Lambda(orExp, Expression.Parameter(typeof(int), "value"));
method.Compile();
如果您需要将 LambdaExpression 转换为不同于二进制代码的内容(例如转换为 SQL 语句),您可能想查看 invoke for invokation 而不是编译表达式
You might wanna look at invoke for invokation instead of compiling the expression, if you need the LambdaExpression to be translated into something different than binary code (E.g. into an SQL statement)
这篇关于Linq2SQL“或/和"运算符(ANDed/ORed 条件)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!