Linq2SQL "or / and" operators (ANDed / ORed conditions)

Let's say we need to apply several conditions to select from the "Things" table (unknown account and nature)

if the conditions are known, we can write

db.Things.Where(t=>foo1 && foo2 || foo3);

      

but if we need to plot this "Where" condition, I can imagine how we can apply the ANDed conditions

IQuerable DesiredThings = db.Things.AsQuerable();
foreach (Condition c in AndedConditions)
DesiredThings = DesiredThings.Where(t => GenerateCondition(c,t));

      

How about ORed conditions? Note: we do not want to perform unions, unique or any other expensive operations, so it is desirable that the request is generated as if we were writing it ad-hock

Thanks in advance.


Adding

PredicateBuilder: Dynamically Generated Expression Predicates

+2


source to share


2 answers


You can use Expression class with static methods to do this runtime.

Below is the code for creating a delegate with one argument called a value of type int.It reads from buttom to the top, so the corresponding line is:

var method = LambdaExpression.Lambda(orExp, Expression.Parameter(typeof(int), "value"));

      

the body of the method compares the value of the parameter with the call to the Bar method of the 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"));

      

Then a similar expression is created and / or



        var orExp = Expression.OrElse(exp1, exp2);

      

The last thing is the call to compile. This call creates a delegate that can be used in your method call.

hope this helps me not 100% sure about the expression to get the value from the 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 may want to call invokation instead of compiling the expression if you need the LambdaExpression to be translated to something other than binary (such as an SQL query)

+5


source


For OR

you, you have two options:

  • use Union

    /Concat

  • write Expression

    in code


The second is closer to .Where(x => {a} || {b})

.

If you are using LINQ-to-SQL you can use Expression.Invoke

to concatenate multiple separate lambda expressions ( see this answer ) - however this is not "t supported in the Entity Framework. In EF, you need to construct the whole expression as one block using Expression.OrElse

; for example here or here .

+2


source







All Articles