Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
296 views
in Technique[技术] by (71.8m points)

c# - Linq2SQL "or/and" operators (ANDed / ORed conditions)

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);

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));

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

Thanks in advance.


Addition:

PredicateBuilder: Dynamically Composing Expression Predicates

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use the Expression class with static methods to do it run time.

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"));

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);

final thing is the call to compile. That call generates a delegate that can be used in your where method call.

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();

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...