Sachin Kainth
Sachin Kainth

Reputation: 46760

Combining Lambda Expressions

I have this method

public Expression<Func<Auction, bool>> GetUnsetDatesAuctionsExpression()
        {
            if (condition)
                return GetAllUnsetDatesAuctionsExpression();
            else
                return (a =>
                        (membershipUser.ProviderUserKey != null) &&
                        (a.OwnerReference == (Guid)membershipUser.ProviderUserKey) &&
                        ((a.Starts == null) || (a.Ends == null)));
            }
        }

which calls this method

private Expression<Func<Auction, bool>> GetAllUnsetDatesAuctionsExpression()
        {
            return (a => (a.Starts == null) || (a.Ends == null));
        }

The issue is that in the above public method I have the below line

(a.Starts == null) || (a.Ends == null)

which is the same as the body of the expression in the private method.

Now, doing this, of course, does not work because you can't AND a bool and an Expression

return (a =>
   (membershipUser.ProviderUserKey != null) &&
   (a.OwnerReference == (Guid)membershipUser.ProviderUserKey) &&
   (GetAllUnsetDatesAuctionsExpression));

So, the question is, how do I combine the call to the private method with

(membershipUser.ProviderUserKey != null) &&
   (a.OwnerReference == (Guid)membershipUser.ProviderUserKey)

Upvotes: 1

Views: 597

Answers (3)

Igor Korkhov
Igor Korkhov

Reputation: 8558

Try the following (I removed superfluous parentheses):

return a =>
    membershipUser.ProviderUserKey != null &&
    a.OwnerReference == (Guid)membershipUser.ProviderUserKey &&
    GetAllUnsetDatesAuctionsExpression().Compile()(a);
    // ---------------------------------^^^^^^^^^^^^^

The code above uses Expression.Compile method to compile the lambda expression described by the expression tree (returned by your GetAllUnsetDatesAuctionsExpression() method) into executable code and produce a delegate that represents the lambda expression.

Edit: I didn't notice that your public method returned an expression, not a value. In your scenario Hans Kesting's approach is much better, of course.

Upvotes: 1

Hans Kesting
Hans Kesting

Reputation: 39338

Create a new expression as a combination of the two, see BinaryExpression:

System.Linq.Expressions.BinaryExpression binaryExpression =
  System.Linq.Expressions.Expression.MakeBinary(
    System.Linq.Expressions.ExpressionType.AndAlso,
    firstExpression,
    secondExpression);

Upvotes: 3

Oded
Oded

Reputation: 499372

Can you not change it the this expression:

return (a => (a.Starts == null || a.Ends == null));

Upvotes: 0

Related Questions