Combining two expressions (Expression<Func>)












205














I have two expressions of type Expression<Func<T, bool>> and I want to take to OR, AND or NOT of these and get a new expression of the same type



Expression<Func<T, bool>> expr1;
Expression<Func<T, bool>> expr2;

...

//how to do this (the code below will obviously not work)
Expression<Func<T, bool>> andExpression = expr AND expr2









share|improve this question




















  • 7




    Very useful post I got from Google: LINQ to Entities: Combining Predicates
    – Thomas C. G. de Vilhena
    Jan 1 '14 at 18:23
















205














I have two expressions of type Expression<Func<T, bool>> and I want to take to OR, AND or NOT of these and get a new expression of the same type



Expression<Func<T, bool>> expr1;
Expression<Func<T, bool>> expr2;

...

//how to do this (the code below will obviously not work)
Expression<Func<T, bool>> andExpression = expr AND expr2









share|improve this question




















  • 7




    Very useful post I got from Google: LINQ to Entities: Combining Predicates
    – Thomas C. G. de Vilhena
    Jan 1 '14 at 18:23














205












205








205


65





I have two expressions of type Expression<Func<T, bool>> and I want to take to OR, AND or NOT of these and get a new expression of the same type



Expression<Func<T, bool>> expr1;
Expression<Func<T, bool>> expr2;

...

//how to do this (the code below will obviously not work)
Expression<Func<T, bool>> andExpression = expr AND expr2









share|improve this question















I have two expressions of type Expression<Func<T, bool>> and I want to take to OR, AND or NOT of these and get a new expression of the same type



Expression<Func<T, bool>> expr1;
Expression<Func<T, bool>> expr2;

...

//how to do this (the code below will obviously not work)
Expression<Func<T, bool>> andExpression = expr AND expr2






c# linq lambda expression






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 27 '09 at 1:04









andy

4,2341160108




4,2341160108










asked Jan 19 '09 at 11:29









BjartN

2,07042030




2,07042030








  • 7




    Very useful post I got from Google: LINQ to Entities: Combining Predicates
    – Thomas C. G. de Vilhena
    Jan 1 '14 at 18:23














  • 7




    Very useful post I got from Google: LINQ to Entities: Combining Predicates
    – Thomas C. G. de Vilhena
    Jan 1 '14 at 18:23








7




7




Very useful post I got from Google: LINQ to Entities: Combining Predicates
– Thomas C. G. de Vilhena
Jan 1 '14 at 18:23




Very useful post I got from Google: LINQ to Entities: Combining Predicates
– Thomas C. G. de Vilhena
Jan 1 '14 at 18:23












7 Answers
7






active

oldest

votes


















259














Well, you can use Expression.AndAlso / OrElse etc to combine logical expressions, but the problem is the parameters; are you working with the same ParameterExpression in expr1 and expr2? If so, it is easier:



var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<T,bool>>(body, expr1.Parameters[0]);


This also works well to negate a single operation:



static Expression<Func<T, bool>> Not<T>(
this Expression<Func<T, bool>> expr)
{
return Expression.Lambda<Func<T, bool>>(
Expression.Not(expr.Body), expr.Parameters[0]);
}


Otherwise, depending on the LINQ provider, you might be able to combine them with Invoke:



// OrElse is very similar...
static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> left,
Expression<Func<T, bool>> right)
{
var param = Expression.Parameter(typeof(T), "x");
var body = Expression.AndAlso(
Expression.Invoke(left, param),
Expression.Invoke(right, param)
);
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
return lambda;
}


Somewhere, I have got some code that re-writes an expression-tree replacing nodes to remove the need for Invoke, but it is quite lengthy (and I can't remember where I left it...)





Generalized version that picks the simplest route:



static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
// need to detect whether they use the same
// parameter instance; if not, they need fixing
ParameterExpression param = expr1.Parameters[0];
if (ReferenceEquals(param, expr2.Parameters[0]))
{
// simple version
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(expr1.Body, expr2.Body), param);
}
// otherwise, keep expr1 "as is" and invoke expr2
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
expr1.Body,
Expression.Invoke(expr2, param)), param);
}


Starting from .net 4.0. There is the ExpressionVistor class which allows you to build expressions that are EF safe.



    public static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var parameter = Expression.Parameter(typeof (T));

var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
var left = leftVisitor.Visit(expr1.Body);

var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
var right = rightVisitor.Visit(expr2.Body);

return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(left, right), parameter);
}



private class ReplaceExpressionVisitor
: ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;

public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}

public override Expression Visit(Expression node)
{
if (node == _oldValue)
return _newValue;
return base.Visit(node);
}
}





share|improve this answer























  • Hey Marc, I tried out your first suggestion, in the your first code block above, but when I pass in the "lambda" expression<func<T,bool>> result in a Where method, I get an error saying the parameter is out of scope? any idea? cheers
    – andy
    Jun 27 '09 at 5:52






  • 1




    +1 the generalized version works like a charm, I used And instead of andalso, I thought linq to sql doesn't support andalso?
    – Maslow
    Sep 4 '09 at 13:57






  • 2




    @Maslow - here's a rewriter that can inline the trees to save Invoke: stackoverflow.com/questions/1717444/…
    – Marc Gravell
    Mar 19 '11 at 21:12






  • 1




    @Aron now look at the date: the .NET framework visitor (ExpressionVisitor) did not exist back then; I have a related example on stackoverflow from a similar date where it implements the visitor manually: it is a lot of code.
    – Marc Gravell
    Aug 13 '14 at 7:09








  • 1




    @MarkGravell, I'm using your first solution to combine my expressions, and everything is working fine even in entityframework, So what would the benefits of using the last solution be?
    – johnny 5
    Aug 3 '17 at 0:08



















44














You can use Expression.AndAlso / OrElse to combine logical expressions, but you have to make sure the ParameterExpressions are the same.



I was having trouble with EF and the PredicateBuilder so I made my own without resorting to Invoke, that I could use like this:



var filterC = filterA.And(filterb);


Source code for my PredicateBuilder:



public static class PredicateBuilder {

public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

ParameterExpression p = a.Parameters[0];

SubstExpressionVisitor visitor = new SubstExpressionVisitor();
visitor.subst[b.Parameters[0]] = p;

Expression body = Expression.AndAlso(a.Body, visitor.Visit(b.Body));
return Expression.Lambda<Func<T, bool>>(body, p);
}

public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

ParameterExpression p = a.Parameters[0];

SubstExpressionVisitor visitor = new SubstExpressionVisitor();
visitor.subst[b.Parameters[0]] = p;

Expression body = Expression.OrElse(a.Body, visitor.Visit(b.Body));
return Expression.Lambda<Func<T, bool>>(body, p);
}
}


And the utility class to substitute the parameters in a lambda:



internal class SubstExpressionVisitor : System.Linq.Expressions.ExpressionVisitor {
public Dictionary<Expression, Expression> subst = new Dictionary<Expression, Expression>();

protected override Expression VisitParameter(ParameterExpression node) {
Expression newValue;
if (subst.TryGetValue(node, out newValue)) {
return newValue;
}
return node;
}
}





share|improve this answer





















  • This solution was the only one that allowed me to have x => x.Property == Value combined with arg => arg.Property2 == Value. Major props, a little terse and confusing but it works so I'm not going to complain. Kudos Adam :-)
    – VulgarBinary
    Dec 12 '12 at 20:38










  • Thanks. I've found the code useful in a lot of places.
    – Adam Tegen
    Dec 13 '12 at 19:10










  • This is a great solution.
    – Aaron Stainback
    May 13 '14 at 23:26










  • Adam, this solved a very annoying problem I was having using the SharePoint Client Object model's Linq provider - thanks for posting it.
    – Christopher McAtackney
    Jul 9 '14 at 14:30










  • This worked for me! I had searched for a variety of solutions as well as predicate builder and nothing worked until this. Thank you!
    – tokyo0709
    Aug 1 '16 at 20:10



















28














Joe Albahari (Author of C# 3.0 in a Nutshell and LINQPad) wrote a utility called PredicateBuilder which can be used to AND and OR functions together.



http://www.albahari.com/nutshell/predicatebuilder.aspx



While it works on functions it is open source so you can check it out and see how it works.






share|improve this answer

















  • 1




    The best solution!! The choosen answer is not as clear as the PredicatedBuilder solution. +1 for that!
    – Eduardo Xavier
    Oct 17 '11 at 16:51










  • @Eduardo: I disagree. PredicateBuilder's code is largely identical to the chosen answer, but the chosen answer provides explanation/code directly instead of via link.
    – Brian
    Mar 30 '12 at 15:37






  • 4




    PredicateBuilder DOES NOT WORK IN EF!!!!!!!!!!!!!!! It evaluates the query from the server then applies the desired predicate in memory instead of passing the predicate to SQL to restrict the result set. This is why PredicateBuilder is not desirable for this use case! BUYER BEWARE
    – VulgarBinary
    Dec 12 '12 at 20:40










  • @VulgarBinary Perhaps you could spend some time figuring out why it doesn't work in EF5 instead of waiting for the answer to be spoon-fed to you.
    – Cameron MacFarland
    Dec 13 '12 at 0:39






  • 1




    @CameronMacFarland I had already written a new PredicateBuilder myself that works and optimizes the expression trees. This snippet gave me the last piece I needed which was the visitor component. I was hardly waiting for anything to be spoon fed, if you seriously want your points back that badly edit your response and I'll take back the -1. However, when someone is looking to do something with Expression<Func<T,bool>> it generally means they want to use EF. Otherwise they would just have used Func<T,bool>
    – VulgarBinary
    Dec 13 '12 at 1:01



















16














If you provider does not support Invoke and you need to combine two expression, you can use an ExpressionVisitor to replace the parameter in the second expression by the parameter in the first expression.



class ParameterUpdateVisitor : ExpressionVisitor
{
private ParameterExpression _oldParameter;
private ParameterExpression _newParameter;

public ParameterUpdateVisitor(ParameterExpression oldParameter, ParameterExpression newParameter)
{
_oldParameter = oldParameter;
_newParameter = newParameter;
}

protected override Expression VisitParameter(ParameterExpression node)
{
if (object.ReferenceEquals(node, _oldParameter))
return _newParameter;

return base.VisitParameter(node);
}
}

static Expression<Func<T, bool>> UpdateParameter<T>(
Expression<Func<T, bool>> expr,
ParameterExpression newParameter)
{
var visitor = new ParameterUpdateVisitor(expr.Parameters[0], newParameter);
var body = visitor.Visit(expr.Body);

return Expression.Lambda<Func<T, bool>>(body, newParameter);
}

[TestMethod]
public void ExpressionText()
{
string text = "test";

Expression<Func<Coco, bool>> expr1 = p => p.Item1.Contains(text);
Expression<Func<Coco, bool>> expr2 = q => q.Item2.Contains(text);
Expression<Func<Coco, bool>> expr3 = UpdateParameter(expr2, expr1.Parameters[0]);

var expr4 = Expression.Lambda<Func<Recording, bool>>(
Expression.OrElse(expr1.Body, expr3.Body), expr1.Parameters[0]);

var func = expr4.Compile();

Assert.IsTrue(func(new Coco { Item1 = "caca", Item2 = "test pipi" }));
}





share|improve this answer



















  • 1




    This solved my particular problem where the other solution resulted in the same exception. Thanks.
    – Shaun Wilson
    Mar 7 '13 at 23:49






  • 1




    This is a great solution.
    – Aaron Stainback
    May 13 '14 at 23:25



















0














I suggest one more improvement to PredicateBuilder and ExpressionVisitor solutions. I called it UnifyParametersByName and you can find it in MIT library of mine: LinqExprHelper. It allows for combining arbitary lambda expressions. Usually the questions are asked about predicate expression, but this idea extends to projection expressions as well.



The following code employs a method ExprAdres which creates a complicated parametrized expression, using inline lambda. This complicated expression is coded only once, and then reused, thanks to the LinqExprHelper mini-library.



public IQueryable<UbezpExt> UbezpFull
{
get
{
System.Linq.Expressions.Expression<
Func<UBEZPIECZONY, UBEZP_ADRES, UBEZP_ADRES, UbezpExt>> expr =
(u, parAdrM, parAdrZ) => new UbezpExt
{
Ub = u,
AdrM = parAdrM,
AdrZ = parAdrZ,
};

// From here an expression builder ExprAdres is called.
var expr2 = expr
.ReplacePar("parAdrM", ExprAdres("M").Body)
.ReplacePar("parAdrZ", ExprAdres("Z").Body);
return UBEZPIECZONY.Select((Expression<Func<UBEZPIECZONY, UbezpExt>>)expr2);
}
}


And this is the subexpression building code:



public static Expression<Func<UBEZPIECZONY, UBEZP_ADRES>> ExprAdres(string sTyp)
{
return u => u.UBEZP_ADRES.Where(a => a.TYP_ADRESU == sTyp)
.OrderByDescending(a => a.DATAOD).FirstOrDefault();
}


What I tried to achieve was to perform parametrized queries without need to copy-paste and with ability to use inline lambdas, which are so pretty. Without all these helper-expression stuff, I would be forced to create whole query in one go.






share|improve this answer





























    0














    I needed to achieve the same results, but using something more generic (as the type was not known). Thanks to marc's answer I finally figured out what I was trying to achieve:



        public static LambdaExpression CombineOr(Type sourceType, LambdaExpression exp, LambdaExpression newExp) 
    {
    var parameter = Expression.Parameter(sourceType);

    var leftVisitor = new ReplaceExpressionVisitor(exp.Parameters[0], parameter);
    var left = leftVisitor.Visit(exp.Body);

    var rightVisitor = new ReplaceExpressionVisitor(newExp.Parameters[0], parameter);
    var right = rightVisitor.Visit(newExp.Body);

    var delegateType = typeof(Func<,>).MakeGenericType(sourceType, typeof(bool));
    return Expression.Lambda(delegateType, Expression.Or(left, right), parameter);
    }





    share|improve this answer





























      -7














      I think this works fine, isn't it ?



      Func<T, bool> expr1 = (x => x.Att1 == "a");
      Func<T, bool> expr2 = (x => x.Att2 == "b");
      Func<T, bool> expr1ANDexpr2 = (x => expr1(x) && expr2(x));
      Func<T, bool> expr1ORexpr2 = (x => expr1(x) || expr2(x));
      Func<T, bool> NOTexpr1 = (x => !expr1(x));





      share|improve this answer

















      • 1




        this cannot be used in Linq to SQL for instance
        – Romain Vergnory
        May 12 '16 at 9:47











      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f457316%2fcombining-two-expressions-expressionfunct-bool%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      259














      Well, you can use Expression.AndAlso / OrElse etc to combine logical expressions, but the problem is the parameters; are you working with the same ParameterExpression in expr1 and expr2? If so, it is easier:



      var body = Expression.AndAlso(expr1.Body, expr2.Body);
      var lambda = Expression.Lambda<Func<T,bool>>(body, expr1.Parameters[0]);


      This also works well to negate a single operation:



      static Expression<Func<T, bool>> Not<T>(
      this Expression<Func<T, bool>> expr)
      {
      return Expression.Lambda<Func<T, bool>>(
      Expression.Not(expr.Body), expr.Parameters[0]);
      }


      Otherwise, depending on the LINQ provider, you might be able to combine them with Invoke:



      // OrElse is very similar...
      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> left,
      Expression<Func<T, bool>> right)
      {
      var param = Expression.Parameter(typeof(T), "x");
      var body = Expression.AndAlso(
      Expression.Invoke(left, param),
      Expression.Invoke(right, param)
      );
      var lambda = Expression.Lambda<Func<T, bool>>(body, param);
      return lambda;
      }


      Somewhere, I have got some code that re-writes an expression-tree replacing nodes to remove the need for Invoke, but it is quite lengthy (and I can't remember where I left it...)





      Generalized version that picks the simplest route:



      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      // need to detect whether they use the same
      // parameter instance; if not, they need fixing
      ParameterExpression param = expr1.Parameters[0];
      if (ReferenceEquals(param, expr2.Parameters[0]))
      {
      // simple version
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(expr1.Body, expr2.Body), param);
      }
      // otherwise, keep expr1 "as is" and invoke expr2
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(
      expr1.Body,
      Expression.Invoke(expr2, param)), param);
      }


      Starting from .net 4.0. There is the ExpressionVistor class which allows you to build expressions that are EF safe.



          public static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      var parameter = Expression.Parameter(typeof (T));

      var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
      var left = leftVisitor.Visit(expr1.Body);

      var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
      var right = rightVisitor.Visit(expr2.Body);

      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(left, right), parameter);
      }



      private class ReplaceExpressionVisitor
      : ExpressionVisitor
      {
      private readonly Expression _oldValue;
      private readonly Expression _newValue;

      public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
      {
      _oldValue = oldValue;
      _newValue = newValue;
      }

      public override Expression Visit(Expression node)
      {
      if (node == _oldValue)
      return _newValue;
      return base.Visit(node);
      }
      }





      share|improve this answer























      • Hey Marc, I tried out your first suggestion, in the your first code block above, but when I pass in the "lambda" expression<func<T,bool>> result in a Where method, I get an error saying the parameter is out of scope? any idea? cheers
        – andy
        Jun 27 '09 at 5:52






      • 1




        +1 the generalized version works like a charm, I used And instead of andalso, I thought linq to sql doesn't support andalso?
        – Maslow
        Sep 4 '09 at 13:57






      • 2




        @Maslow - here's a rewriter that can inline the trees to save Invoke: stackoverflow.com/questions/1717444/…
        – Marc Gravell
        Mar 19 '11 at 21:12






      • 1




        @Aron now look at the date: the .NET framework visitor (ExpressionVisitor) did not exist back then; I have a related example on stackoverflow from a similar date where it implements the visitor manually: it is a lot of code.
        – Marc Gravell
        Aug 13 '14 at 7:09








      • 1




        @MarkGravell, I'm using your first solution to combine my expressions, and everything is working fine even in entityframework, So what would the benefits of using the last solution be?
        – johnny 5
        Aug 3 '17 at 0:08
















      259














      Well, you can use Expression.AndAlso / OrElse etc to combine logical expressions, but the problem is the parameters; are you working with the same ParameterExpression in expr1 and expr2? If so, it is easier:



      var body = Expression.AndAlso(expr1.Body, expr2.Body);
      var lambda = Expression.Lambda<Func<T,bool>>(body, expr1.Parameters[0]);


      This also works well to negate a single operation:



      static Expression<Func<T, bool>> Not<T>(
      this Expression<Func<T, bool>> expr)
      {
      return Expression.Lambda<Func<T, bool>>(
      Expression.Not(expr.Body), expr.Parameters[0]);
      }


      Otherwise, depending on the LINQ provider, you might be able to combine them with Invoke:



      // OrElse is very similar...
      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> left,
      Expression<Func<T, bool>> right)
      {
      var param = Expression.Parameter(typeof(T), "x");
      var body = Expression.AndAlso(
      Expression.Invoke(left, param),
      Expression.Invoke(right, param)
      );
      var lambda = Expression.Lambda<Func<T, bool>>(body, param);
      return lambda;
      }


      Somewhere, I have got some code that re-writes an expression-tree replacing nodes to remove the need for Invoke, but it is quite lengthy (and I can't remember where I left it...)





      Generalized version that picks the simplest route:



      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      // need to detect whether they use the same
      // parameter instance; if not, they need fixing
      ParameterExpression param = expr1.Parameters[0];
      if (ReferenceEquals(param, expr2.Parameters[0]))
      {
      // simple version
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(expr1.Body, expr2.Body), param);
      }
      // otherwise, keep expr1 "as is" and invoke expr2
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(
      expr1.Body,
      Expression.Invoke(expr2, param)), param);
      }


      Starting from .net 4.0. There is the ExpressionVistor class which allows you to build expressions that are EF safe.



          public static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      var parameter = Expression.Parameter(typeof (T));

      var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
      var left = leftVisitor.Visit(expr1.Body);

      var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
      var right = rightVisitor.Visit(expr2.Body);

      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(left, right), parameter);
      }



      private class ReplaceExpressionVisitor
      : ExpressionVisitor
      {
      private readonly Expression _oldValue;
      private readonly Expression _newValue;

      public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
      {
      _oldValue = oldValue;
      _newValue = newValue;
      }

      public override Expression Visit(Expression node)
      {
      if (node == _oldValue)
      return _newValue;
      return base.Visit(node);
      }
      }





      share|improve this answer























      • Hey Marc, I tried out your first suggestion, in the your first code block above, but when I pass in the "lambda" expression<func<T,bool>> result in a Where method, I get an error saying the parameter is out of scope? any idea? cheers
        – andy
        Jun 27 '09 at 5:52






      • 1




        +1 the generalized version works like a charm, I used And instead of andalso, I thought linq to sql doesn't support andalso?
        – Maslow
        Sep 4 '09 at 13:57






      • 2




        @Maslow - here's a rewriter that can inline the trees to save Invoke: stackoverflow.com/questions/1717444/…
        – Marc Gravell
        Mar 19 '11 at 21:12






      • 1




        @Aron now look at the date: the .NET framework visitor (ExpressionVisitor) did not exist back then; I have a related example on stackoverflow from a similar date where it implements the visitor manually: it is a lot of code.
        – Marc Gravell
        Aug 13 '14 at 7:09








      • 1




        @MarkGravell, I'm using your first solution to combine my expressions, and everything is working fine even in entityframework, So what would the benefits of using the last solution be?
        – johnny 5
        Aug 3 '17 at 0:08














      259












      259








      259






      Well, you can use Expression.AndAlso / OrElse etc to combine logical expressions, but the problem is the parameters; are you working with the same ParameterExpression in expr1 and expr2? If so, it is easier:



      var body = Expression.AndAlso(expr1.Body, expr2.Body);
      var lambda = Expression.Lambda<Func<T,bool>>(body, expr1.Parameters[0]);


      This also works well to negate a single operation:



      static Expression<Func<T, bool>> Not<T>(
      this Expression<Func<T, bool>> expr)
      {
      return Expression.Lambda<Func<T, bool>>(
      Expression.Not(expr.Body), expr.Parameters[0]);
      }


      Otherwise, depending on the LINQ provider, you might be able to combine them with Invoke:



      // OrElse is very similar...
      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> left,
      Expression<Func<T, bool>> right)
      {
      var param = Expression.Parameter(typeof(T), "x");
      var body = Expression.AndAlso(
      Expression.Invoke(left, param),
      Expression.Invoke(right, param)
      );
      var lambda = Expression.Lambda<Func<T, bool>>(body, param);
      return lambda;
      }


      Somewhere, I have got some code that re-writes an expression-tree replacing nodes to remove the need for Invoke, but it is quite lengthy (and I can't remember where I left it...)





      Generalized version that picks the simplest route:



      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      // need to detect whether they use the same
      // parameter instance; if not, they need fixing
      ParameterExpression param = expr1.Parameters[0];
      if (ReferenceEquals(param, expr2.Parameters[0]))
      {
      // simple version
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(expr1.Body, expr2.Body), param);
      }
      // otherwise, keep expr1 "as is" and invoke expr2
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(
      expr1.Body,
      Expression.Invoke(expr2, param)), param);
      }


      Starting from .net 4.0. There is the ExpressionVistor class which allows you to build expressions that are EF safe.



          public static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      var parameter = Expression.Parameter(typeof (T));

      var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
      var left = leftVisitor.Visit(expr1.Body);

      var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
      var right = rightVisitor.Visit(expr2.Body);

      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(left, right), parameter);
      }



      private class ReplaceExpressionVisitor
      : ExpressionVisitor
      {
      private readonly Expression _oldValue;
      private readonly Expression _newValue;

      public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
      {
      _oldValue = oldValue;
      _newValue = newValue;
      }

      public override Expression Visit(Expression node)
      {
      if (node == _oldValue)
      return _newValue;
      return base.Visit(node);
      }
      }





      share|improve this answer














      Well, you can use Expression.AndAlso / OrElse etc to combine logical expressions, but the problem is the parameters; are you working with the same ParameterExpression in expr1 and expr2? If so, it is easier:



      var body = Expression.AndAlso(expr1.Body, expr2.Body);
      var lambda = Expression.Lambda<Func<T,bool>>(body, expr1.Parameters[0]);


      This also works well to negate a single operation:



      static Expression<Func<T, bool>> Not<T>(
      this Expression<Func<T, bool>> expr)
      {
      return Expression.Lambda<Func<T, bool>>(
      Expression.Not(expr.Body), expr.Parameters[0]);
      }


      Otherwise, depending on the LINQ provider, you might be able to combine them with Invoke:



      // OrElse is very similar...
      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> left,
      Expression<Func<T, bool>> right)
      {
      var param = Expression.Parameter(typeof(T), "x");
      var body = Expression.AndAlso(
      Expression.Invoke(left, param),
      Expression.Invoke(right, param)
      );
      var lambda = Expression.Lambda<Func<T, bool>>(body, param);
      return lambda;
      }


      Somewhere, I have got some code that re-writes an expression-tree replacing nodes to remove the need for Invoke, but it is quite lengthy (and I can't remember where I left it...)





      Generalized version that picks the simplest route:



      static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      // need to detect whether they use the same
      // parameter instance; if not, they need fixing
      ParameterExpression param = expr1.Parameters[0];
      if (ReferenceEquals(param, expr2.Parameters[0]))
      {
      // simple version
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(expr1.Body, expr2.Body), param);
      }
      // otherwise, keep expr1 "as is" and invoke expr2
      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(
      expr1.Body,
      Expression.Invoke(expr2, param)), param);
      }


      Starting from .net 4.0. There is the ExpressionVistor class which allows you to build expressions that are EF safe.



          public static Expression<Func<T, bool>> AndAlso<T>(
      this Expression<Func<T, bool>> expr1,
      Expression<Func<T, bool>> expr2)
      {
      var parameter = Expression.Parameter(typeof (T));

      var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
      var left = leftVisitor.Visit(expr1.Body);

      var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
      var right = rightVisitor.Visit(expr2.Body);

      return Expression.Lambda<Func<T, bool>>(
      Expression.AndAlso(left, right), parameter);
      }



      private class ReplaceExpressionVisitor
      : ExpressionVisitor
      {
      private readonly Expression _oldValue;
      private readonly Expression _newValue;

      public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
      {
      _oldValue = oldValue;
      _newValue = newValue;
      }

      public override Expression Visit(Expression node)
      {
      if (node == _oldValue)
      return _newValue;
      return base.Visit(node);
      }
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Feb 27 '15 at 10:55







      user3934443

















      answered Jan 19 '09 at 11:32









      Marc Gravell

      777k19221262539




      777k19221262539












      • Hey Marc, I tried out your first suggestion, in the your first code block above, but when I pass in the "lambda" expression<func<T,bool>> result in a Where method, I get an error saying the parameter is out of scope? any idea? cheers
        – andy
        Jun 27 '09 at 5:52






      • 1




        +1 the generalized version works like a charm, I used And instead of andalso, I thought linq to sql doesn't support andalso?
        – Maslow
        Sep 4 '09 at 13:57






      • 2




        @Maslow - here's a rewriter that can inline the trees to save Invoke: stackoverflow.com/questions/1717444/…
        – Marc Gravell
        Mar 19 '11 at 21:12






      • 1




        @Aron now look at the date: the .NET framework visitor (ExpressionVisitor) did not exist back then; I have a related example on stackoverflow from a similar date where it implements the visitor manually: it is a lot of code.
        – Marc Gravell
        Aug 13 '14 at 7:09








      • 1




        @MarkGravell, I'm using your first solution to combine my expressions, and everything is working fine even in entityframework, So what would the benefits of using the last solution be?
        – johnny 5
        Aug 3 '17 at 0:08


















      • Hey Marc, I tried out your first suggestion, in the your first code block above, but when I pass in the "lambda" expression<func<T,bool>> result in a Where method, I get an error saying the parameter is out of scope? any idea? cheers
        – andy
        Jun 27 '09 at 5:52






      • 1




        +1 the generalized version works like a charm, I used And instead of andalso, I thought linq to sql doesn't support andalso?
        – Maslow
        Sep 4 '09 at 13:57






      • 2




        @Maslow - here's a rewriter that can inline the trees to save Invoke: stackoverflow.com/questions/1717444/…
        – Marc Gravell
        Mar 19 '11 at 21:12






      • 1




        @Aron now look at the date: the .NET framework visitor (ExpressionVisitor) did not exist back then; I have a related example on stackoverflow from a similar date where it implements the visitor manually: it is a lot of code.
        – Marc Gravell
        Aug 13 '14 at 7:09








      • 1




        @MarkGravell, I'm using your first solution to combine my expressions, and everything is working fine even in entityframework, So what would the benefits of using the last solution be?
        – johnny 5
        Aug 3 '17 at 0:08
















      Hey Marc, I tried out your first suggestion, in the your first code block above, but when I pass in the "lambda" expression<func<T,bool>> result in a Where method, I get an error saying the parameter is out of scope? any idea? cheers
      – andy
      Jun 27 '09 at 5:52




      Hey Marc, I tried out your first suggestion, in the your first code block above, but when I pass in the "lambda" expression<func<T,bool>> result in a Where method, I get an error saying the parameter is out of scope? any idea? cheers
      – andy
      Jun 27 '09 at 5:52




      1




      1




      +1 the generalized version works like a charm, I used And instead of andalso, I thought linq to sql doesn't support andalso?
      – Maslow
      Sep 4 '09 at 13:57




      +1 the generalized version works like a charm, I used And instead of andalso, I thought linq to sql doesn't support andalso?
      – Maslow
      Sep 4 '09 at 13:57




      2




      2




      @Maslow - here's a rewriter that can inline the trees to save Invoke: stackoverflow.com/questions/1717444/…
      – Marc Gravell
      Mar 19 '11 at 21:12




      @Maslow - here's a rewriter that can inline the trees to save Invoke: stackoverflow.com/questions/1717444/…
      – Marc Gravell
      Mar 19 '11 at 21:12




      1




      1




      @Aron now look at the date: the .NET framework visitor (ExpressionVisitor) did not exist back then; I have a related example on stackoverflow from a similar date where it implements the visitor manually: it is a lot of code.
      – Marc Gravell
      Aug 13 '14 at 7:09






      @Aron now look at the date: the .NET framework visitor (ExpressionVisitor) did not exist back then; I have a related example on stackoverflow from a similar date where it implements the visitor manually: it is a lot of code.
      – Marc Gravell
      Aug 13 '14 at 7:09






      1




      1




      @MarkGravell, I'm using your first solution to combine my expressions, and everything is working fine even in entityframework, So what would the benefits of using the last solution be?
      – johnny 5
      Aug 3 '17 at 0:08




      @MarkGravell, I'm using your first solution to combine my expressions, and everything is working fine even in entityframework, So what would the benefits of using the last solution be?
      – johnny 5
      Aug 3 '17 at 0:08













      44














      You can use Expression.AndAlso / OrElse to combine logical expressions, but you have to make sure the ParameterExpressions are the same.



      I was having trouble with EF and the PredicateBuilder so I made my own without resorting to Invoke, that I could use like this:



      var filterC = filterA.And(filterb);


      Source code for my PredicateBuilder:



      public static class PredicateBuilder {

      public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.AndAlso(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }

      public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.OrElse(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }
      }


      And the utility class to substitute the parameters in a lambda:



      internal class SubstExpressionVisitor : System.Linq.Expressions.ExpressionVisitor {
      public Dictionary<Expression, Expression> subst = new Dictionary<Expression, Expression>();

      protected override Expression VisitParameter(ParameterExpression node) {
      Expression newValue;
      if (subst.TryGetValue(node, out newValue)) {
      return newValue;
      }
      return node;
      }
      }





      share|improve this answer





















      • This solution was the only one that allowed me to have x => x.Property == Value combined with arg => arg.Property2 == Value. Major props, a little terse and confusing but it works so I'm not going to complain. Kudos Adam :-)
        – VulgarBinary
        Dec 12 '12 at 20:38










      • Thanks. I've found the code useful in a lot of places.
        – Adam Tegen
        Dec 13 '12 at 19:10










      • This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:26










      • Adam, this solved a very annoying problem I was having using the SharePoint Client Object model's Linq provider - thanks for posting it.
        – Christopher McAtackney
        Jul 9 '14 at 14:30










      • This worked for me! I had searched for a variety of solutions as well as predicate builder and nothing worked until this. Thank you!
        – tokyo0709
        Aug 1 '16 at 20:10
















      44














      You can use Expression.AndAlso / OrElse to combine logical expressions, but you have to make sure the ParameterExpressions are the same.



      I was having trouble with EF and the PredicateBuilder so I made my own without resorting to Invoke, that I could use like this:



      var filterC = filterA.And(filterb);


      Source code for my PredicateBuilder:



      public static class PredicateBuilder {

      public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.AndAlso(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }

      public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.OrElse(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }
      }


      And the utility class to substitute the parameters in a lambda:



      internal class SubstExpressionVisitor : System.Linq.Expressions.ExpressionVisitor {
      public Dictionary<Expression, Expression> subst = new Dictionary<Expression, Expression>();

      protected override Expression VisitParameter(ParameterExpression node) {
      Expression newValue;
      if (subst.TryGetValue(node, out newValue)) {
      return newValue;
      }
      return node;
      }
      }





      share|improve this answer





















      • This solution was the only one that allowed me to have x => x.Property == Value combined with arg => arg.Property2 == Value. Major props, a little terse and confusing but it works so I'm not going to complain. Kudos Adam :-)
        – VulgarBinary
        Dec 12 '12 at 20:38










      • Thanks. I've found the code useful in a lot of places.
        – Adam Tegen
        Dec 13 '12 at 19:10










      • This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:26










      • Adam, this solved a very annoying problem I was having using the SharePoint Client Object model's Linq provider - thanks for posting it.
        – Christopher McAtackney
        Jul 9 '14 at 14:30










      • This worked for me! I had searched for a variety of solutions as well as predicate builder and nothing worked until this. Thank you!
        – tokyo0709
        Aug 1 '16 at 20:10














      44












      44








      44






      You can use Expression.AndAlso / OrElse to combine logical expressions, but you have to make sure the ParameterExpressions are the same.



      I was having trouble with EF and the PredicateBuilder so I made my own without resorting to Invoke, that I could use like this:



      var filterC = filterA.And(filterb);


      Source code for my PredicateBuilder:



      public static class PredicateBuilder {

      public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.AndAlso(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }

      public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.OrElse(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }
      }


      And the utility class to substitute the parameters in a lambda:



      internal class SubstExpressionVisitor : System.Linq.Expressions.ExpressionVisitor {
      public Dictionary<Expression, Expression> subst = new Dictionary<Expression, Expression>();

      protected override Expression VisitParameter(ParameterExpression node) {
      Expression newValue;
      if (subst.TryGetValue(node, out newValue)) {
      return newValue;
      }
      return node;
      }
      }





      share|improve this answer












      You can use Expression.AndAlso / OrElse to combine logical expressions, but you have to make sure the ParameterExpressions are the same.



      I was having trouble with EF and the PredicateBuilder so I made my own without resorting to Invoke, that I could use like this:



      var filterC = filterA.And(filterb);


      Source code for my PredicateBuilder:



      public static class PredicateBuilder {

      public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.AndAlso(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }

      public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {

      ParameterExpression p = a.Parameters[0];

      SubstExpressionVisitor visitor = new SubstExpressionVisitor();
      visitor.subst[b.Parameters[0]] = p;

      Expression body = Expression.OrElse(a.Body, visitor.Visit(b.Body));
      return Expression.Lambda<Func<T, bool>>(body, p);
      }
      }


      And the utility class to substitute the parameters in a lambda:



      internal class SubstExpressionVisitor : System.Linq.Expressions.ExpressionVisitor {
      public Dictionary<Expression, Expression> subst = new Dictionary<Expression, Expression>();

      protected override Expression VisitParameter(ParameterExpression node) {
      Expression newValue;
      if (subst.TryGetValue(node, out newValue)) {
      return newValue;
      }
      return node;
      }
      }






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Sep 19 '12 at 14:53









      Adam Tegen

      13.8k30109145




      13.8k30109145












      • This solution was the only one that allowed me to have x => x.Property == Value combined with arg => arg.Property2 == Value. Major props, a little terse and confusing but it works so I'm not going to complain. Kudos Adam :-)
        – VulgarBinary
        Dec 12 '12 at 20:38










      • Thanks. I've found the code useful in a lot of places.
        – Adam Tegen
        Dec 13 '12 at 19:10










      • This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:26










      • Adam, this solved a very annoying problem I was having using the SharePoint Client Object model's Linq provider - thanks for posting it.
        – Christopher McAtackney
        Jul 9 '14 at 14:30










      • This worked for me! I had searched for a variety of solutions as well as predicate builder and nothing worked until this. Thank you!
        – tokyo0709
        Aug 1 '16 at 20:10


















      • This solution was the only one that allowed me to have x => x.Property == Value combined with arg => arg.Property2 == Value. Major props, a little terse and confusing but it works so I'm not going to complain. Kudos Adam :-)
        – VulgarBinary
        Dec 12 '12 at 20:38










      • Thanks. I've found the code useful in a lot of places.
        – Adam Tegen
        Dec 13 '12 at 19:10










      • This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:26










      • Adam, this solved a very annoying problem I was having using the SharePoint Client Object model's Linq provider - thanks for posting it.
        – Christopher McAtackney
        Jul 9 '14 at 14:30










      • This worked for me! I had searched for a variety of solutions as well as predicate builder and nothing worked until this. Thank you!
        – tokyo0709
        Aug 1 '16 at 20:10
















      This solution was the only one that allowed me to have x => x.Property == Value combined with arg => arg.Property2 == Value. Major props, a little terse and confusing but it works so I'm not going to complain. Kudos Adam :-)
      – VulgarBinary
      Dec 12 '12 at 20:38




      This solution was the only one that allowed me to have x => x.Property == Value combined with arg => arg.Property2 == Value. Major props, a little terse and confusing but it works so I'm not going to complain. Kudos Adam :-)
      – VulgarBinary
      Dec 12 '12 at 20:38












      Thanks. I've found the code useful in a lot of places.
      – Adam Tegen
      Dec 13 '12 at 19:10




      Thanks. I've found the code useful in a lot of places.
      – Adam Tegen
      Dec 13 '12 at 19:10












      This is a great solution.
      – Aaron Stainback
      May 13 '14 at 23:26




      This is a great solution.
      – Aaron Stainback
      May 13 '14 at 23:26












      Adam, this solved a very annoying problem I was having using the SharePoint Client Object model's Linq provider - thanks for posting it.
      – Christopher McAtackney
      Jul 9 '14 at 14:30




      Adam, this solved a very annoying problem I was having using the SharePoint Client Object model's Linq provider - thanks for posting it.
      – Christopher McAtackney
      Jul 9 '14 at 14:30












      This worked for me! I had searched for a variety of solutions as well as predicate builder and nothing worked until this. Thank you!
      – tokyo0709
      Aug 1 '16 at 20:10




      This worked for me! I had searched for a variety of solutions as well as predicate builder and nothing worked until this. Thank you!
      – tokyo0709
      Aug 1 '16 at 20:10











      28














      Joe Albahari (Author of C# 3.0 in a Nutshell and LINQPad) wrote a utility called PredicateBuilder which can be used to AND and OR functions together.



      http://www.albahari.com/nutshell/predicatebuilder.aspx



      While it works on functions it is open source so you can check it out and see how it works.






      share|improve this answer

















      • 1




        The best solution!! The choosen answer is not as clear as the PredicatedBuilder solution. +1 for that!
        – Eduardo Xavier
        Oct 17 '11 at 16:51










      • @Eduardo: I disagree. PredicateBuilder's code is largely identical to the chosen answer, but the chosen answer provides explanation/code directly instead of via link.
        – Brian
        Mar 30 '12 at 15:37






      • 4




        PredicateBuilder DOES NOT WORK IN EF!!!!!!!!!!!!!!! It evaluates the query from the server then applies the desired predicate in memory instead of passing the predicate to SQL to restrict the result set. This is why PredicateBuilder is not desirable for this use case! BUYER BEWARE
        – VulgarBinary
        Dec 12 '12 at 20:40










      • @VulgarBinary Perhaps you could spend some time figuring out why it doesn't work in EF5 instead of waiting for the answer to be spoon-fed to you.
        – Cameron MacFarland
        Dec 13 '12 at 0:39






      • 1




        @CameronMacFarland I had already written a new PredicateBuilder myself that works and optimizes the expression trees. This snippet gave me the last piece I needed which was the visitor component. I was hardly waiting for anything to be spoon fed, if you seriously want your points back that badly edit your response and I'll take back the -1. However, when someone is looking to do something with Expression<Func<T,bool>> it generally means they want to use EF. Otherwise they would just have used Func<T,bool>
        – VulgarBinary
        Dec 13 '12 at 1:01
















      28














      Joe Albahari (Author of C# 3.0 in a Nutshell and LINQPad) wrote a utility called PredicateBuilder which can be used to AND and OR functions together.



      http://www.albahari.com/nutshell/predicatebuilder.aspx



      While it works on functions it is open source so you can check it out and see how it works.






      share|improve this answer

















      • 1




        The best solution!! The choosen answer is not as clear as the PredicatedBuilder solution. +1 for that!
        – Eduardo Xavier
        Oct 17 '11 at 16:51










      • @Eduardo: I disagree. PredicateBuilder's code is largely identical to the chosen answer, but the chosen answer provides explanation/code directly instead of via link.
        – Brian
        Mar 30 '12 at 15:37






      • 4




        PredicateBuilder DOES NOT WORK IN EF!!!!!!!!!!!!!!! It evaluates the query from the server then applies the desired predicate in memory instead of passing the predicate to SQL to restrict the result set. This is why PredicateBuilder is not desirable for this use case! BUYER BEWARE
        – VulgarBinary
        Dec 12 '12 at 20:40










      • @VulgarBinary Perhaps you could spend some time figuring out why it doesn't work in EF5 instead of waiting for the answer to be spoon-fed to you.
        – Cameron MacFarland
        Dec 13 '12 at 0:39






      • 1




        @CameronMacFarland I had already written a new PredicateBuilder myself that works and optimizes the expression trees. This snippet gave me the last piece I needed which was the visitor component. I was hardly waiting for anything to be spoon fed, if you seriously want your points back that badly edit your response and I'll take back the -1. However, when someone is looking to do something with Expression<Func<T,bool>> it generally means they want to use EF. Otherwise they would just have used Func<T,bool>
        – VulgarBinary
        Dec 13 '12 at 1:01














      28












      28








      28






      Joe Albahari (Author of C# 3.0 in a Nutshell and LINQPad) wrote a utility called PredicateBuilder which can be used to AND and OR functions together.



      http://www.albahari.com/nutshell/predicatebuilder.aspx



      While it works on functions it is open source so you can check it out and see how it works.






      share|improve this answer












      Joe Albahari (Author of C# 3.0 in a Nutshell and LINQPad) wrote a utility called PredicateBuilder which can be used to AND and OR functions together.



      http://www.albahari.com/nutshell/predicatebuilder.aspx



      While it works on functions it is open source so you can check it out and see how it works.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jan 19 '09 at 22:52









      Cameron MacFarland

      52.2k1892120




      52.2k1892120








      • 1




        The best solution!! The choosen answer is not as clear as the PredicatedBuilder solution. +1 for that!
        – Eduardo Xavier
        Oct 17 '11 at 16:51










      • @Eduardo: I disagree. PredicateBuilder's code is largely identical to the chosen answer, but the chosen answer provides explanation/code directly instead of via link.
        – Brian
        Mar 30 '12 at 15:37






      • 4




        PredicateBuilder DOES NOT WORK IN EF!!!!!!!!!!!!!!! It evaluates the query from the server then applies the desired predicate in memory instead of passing the predicate to SQL to restrict the result set. This is why PredicateBuilder is not desirable for this use case! BUYER BEWARE
        – VulgarBinary
        Dec 12 '12 at 20:40










      • @VulgarBinary Perhaps you could spend some time figuring out why it doesn't work in EF5 instead of waiting for the answer to be spoon-fed to you.
        – Cameron MacFarland
        Dec 13 '12 at 0:39






      • 1




        @CameronMacFarland I had already written a new PredicateBuilder myself that works and optimizes the expression trees. This snippet gave me the last piece I needed which was the visitor component. I was hardly waiting for anything to be spoon fed, if you seriously want your points back that badly edit your response and I'll take back the -1. However, when someone is looking to do something with Expression<Func<T,bool>> it generally means they want to use EF. Otherwise they would just have used Func<T,bool>
        – VulgarBinary
        Dec 13 '12 at 1:01














      • 1




        The best solution!! The choosen answer is not as clear as the PredicatedBuilder solution. +1 for that!
        – Eduardo Xavier
        Oct 17 '11 at 16:51










      • @Eduardo: I disagree. PredicateBuilder's code is largely identical to the chosen answer, but the chosen answer provides explanation/code directly instead of via link.
        – Brian
        Mar 30 '12 at 15:37






      • 4




        PredicateBuilder DOES NOT WORK IN EF!!!!!!!!!!!!!!! It evaluates the query from the server then applies the desired predicate in memory instead of passing the predicate to SQL to restrict the result set. This is why PredicateBuilder is not desirable for this use case! BUYER BEWARE
        – VulgarBinary
        Dec 12 '12 at 20:40










      • @VulgarBinary Perhaps you could spend some time figuring out why it doesn't work in EF5 instead of waiting for the answer to be spoon-fed to you.
        – Cameron MacFarland
        Dec 13 '12 at 0:39






      • 1




        @CameronMacFarland I had already written a new PredicateBuilder myself that works and optimizes the expression trees. This snippet gave me the last piece I needed which was the visitor component. I was hardly waiting for anything to be spoon fed, if you seriously want your points back that badly edit your response and I'll take back the -1. However, when someone is looking to do something with Expression<Func<T,bool>> it generally means they want to use EF. Otherwise they would just have used Func<T,bool>
        – VulgarBinary
        Dec 13 '12 at 1:01








      1




      1




      The best solution!! The choosen answer is not as clear as the PredicatedBuilder solution. +1 for that!
      – Eduardo Xavier
      Oct 17 '11 at 16:51




      The best solution!! The choosen answer is not as clear as the PredicatedBuilder solution. +1 for that!
      – Eduardo Xavier
      Oct 17 '11 at 16:51












      @Eduardo: I disagree. PredicateBuilder's code is largely identical to the chosen answer, but the chosen answer provides explanation/code directly instead of via link.
      – Brian
      Mar 30 '12 at 15:37




      @Eduardo: I disagree. PredicateBuilder's code is largely identical to the chosen answer, but the chosen answer provides explanation/code directly instead of via link.
      – Brian
      Mar 30 '12 at 15:37




      4




      4




      PredicateBuilder DOES NOT WORK IN EF!!!!!!!!!!!!!!! It evaluates the query from the server then applies the desired predicate in memory instead of passing the predicate to SQL to restrict the result set. This is why PredicateBuilder is not desirable for this use case! BUYER BEWARE
      – VulgarBinary
      Dec 12 '12 at 20:40




      PredicateBuilder DOES NOT WORK IN EF!!!!!!!!!!!!!!! It evaluates the query from the server then applies the desired predicate in memory instead of passing the predicate to SQL to restrict the result set. This is why PredicateBuilder is not desirable for this use case! BUYER BEWARE
      – VulgarBinary
      Dec 12 '12 at 20:40












      @VulgarBinary Perhaps you could spend some time figuring out why it doesn't work in EF5 instead of waiting for the answer to be spoon-fed to you.
      – Cameron MacFarland
      Dec 13 '12 at 0:39




      @VulgarBinary Perhaps you could spend some time figuring out why it doesn't work in EF5 instead of waiting for the answer to be spoon-fed to you.
      – Cameron MacFarland
      Dec 13 '12 at 0:39




      1




      1




      @CameronMacFarland I had already written a new PredicateBuilder myself that works and optimizes the expression trees. This snippet gave me the last piece I needed which was the visitor component. I was hardly waiting for anything to be spoon fed, if you seriously want your points back that badly edit your response and I'll take back the -1. However, when someone is looking to do something with Expression<Func<T,bool>> it generally means they want to use EF. Otherwise they would just have used Func<T,bool>
      – VulgarBinary
      Dec 13 '12 at 1:01




      @CameronMacFarland I had already written a new PredicateBuilder myself that works and optimizes the expression trees. This snippet gave me the last piece I needed which was the visitor component. I was hardly waiting for anything to be spoon fed, if you seriously want your points back that badly edit your response and I'll take back the -1. However, when someone is looking to do something with Expression<Func<T,bool>> it generally means they want to use EF. Otherwise they would just have used Func<T,bool>
      – VulgarBinary
      Dec 13 '12 at 1:01











      16














      If you provider does not support Invoke and you need to combine two expression, you can use an ExpressionVisitor to replace the parameter in the second expression by the parameter in the first expression.



      class ParameterUpdateVisitor : ExpressionVisitor
      {
      private ParameterExpression _oldParameter;
      private ParameterExpression _newParameter;

      public ParameterUpdateVisitor(ParameterExpression oldParameter, ParameterExpression newParameter)
      {
      _oldParameter = oldParameter;
      _newParameter = newParameter;
      }

      protected override Expression VisitParameter(ParameterExpression node)
      {
      if (object.ReferenceEquals(node, _oldParameter))
      return _newParameter;

      return base.VisitParameter(node);
      }
      }

      static Expression<Func<T, bool>> UpdateParameter<T>(
      Expression<Func<T, bool>> expr,
      ParameterExpression newParameter)
      {
      var visitor = new ParameterUpdateVisitor(expr.Parameters[0], newParameter);
      var body = visitor.Visit(expr.Body);

      return Expression.Lambda<Func<T, bool>>(body, newParameter);
      }

      [TestMethod]
      public void ExpressionText()
      {
      string text = "test";

      Expression<Func<Coco, bool>> expr1 = p => p.Item1.Contains(text);
      Expression<Func<Coco, bool>> expr2 = q => q.Item2.Contains(text);
      Expression<Func<Coco, bool>> expr3 = UpdateParameter(expr2, expr1.Parameters[0]);

      var expr4 = Expression.Lambda<Func<Recording, bool>>(
      Expression.OrElse(expr1.Body, expr3.Body), expr1.Parameters[0]);

      var func = expr4.Compile();

      Assert.IsTrue(func(new Coco { Item1 = "caca", Item2 = "test pipi" }));
      }





      share|improve this answer



















      • 1




        This solved my particular problem where the other solution resulted in the same exception. Thanks.
        – Shaun Wilson
        Mar 7 '13 at 23:49






      • 1




        This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:25
















      16














      If you provider does not support Invoke and you need to combine two expression, you can use an ExpressionVisitor to replace the parameter in the second expression by the parameter in the first expression.



      class ParameterUpdateVisitor : ExpressionVisitor
      {
      private ParameterExpression _oldParameter;
      private ParameterExpression _newParameter;

      public ParameterUpdateVisitor(ParameterExpression oldParameter, ParameterExpression newParameter)
      {
      _oldParameter = oldParameter;
      _newParameter = newParameter;
      }

      protected override Expression VisitParameter(ParameterExpression node)
      {
      if (object.ReferenceEquals(node, _oldParameter))
      return _newParameter;

      return base.VisitParameter(node);
      }
      }

      static Expression<Func<T, bool>> UpdateParameter<T>(
      Expression<Func<T, bool>> expr,
      ParameterExpression newParameter)
      {
      var visitor = new ParameterUpdateVisitor(expr.Parameters[0], newParameter);
      var body = visitor.Visit(expr.Body);

      return Expression.Lambda<Func<T, bool>>(body, newParameter);
      }

      [TestMethod]
      public void ExpressionText()
      {
      string text = "test";

      Expression<Func<Coco, bool>> expr1 = p => p.Item1.Contains(text);
      Expression<Func<Coco, bool>> expr2 = q => q.Item2.Contains(text);
      Expression<Func<Coco, bool>> expr3 = UpdateParameter(expr2, expr1.Parameters[0]);

      var expr4 = Expression.Lambda<Func<Recording, bool>>(
      Expression.OrElse(expr1.Body, expr3.Body), expr1.Parameters[0]);

      var func = expr4.Compile();

      Assert.IsTrue(func(new Coco { Item1 = "caca", Item2 = "test pipi" }));
      }





      share|improve this answer



















      • 1




        This solved my particular problem where the other solution resulted in the same exception. Thanks.
        – Shaun Wilson
        Mar 7 '13 at 23:49






      • 1




        This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:25














      16












      16








      16






      If you provider does not support Invoke and you need to combine two expression, you can use an ExpressionVisitor to replace the parameter in the second expression by the parameter in the first expression.



      class ParameterUpdateVisitor : ExpressionVisitor
      {
      private ParameterExpression _oldParameter;
      private ParameterExpression _newParameter;

      public ParameterUpdateVisitor(ParameterExpression oldParameter, ParameterExpression newParameter)
      {
      _oldParameter = oldParameter;
      _newParameter = newParameter;
      }

      protected override Expression VisitParameter(ParameterExpression node)
      {
      if (object.ReferenceEquals(node, _oldParameter))
      return _newParameter;

      return base.VisitParameter(node);
      }
      }

      static Expression<Func<T, bool>> UpdateParameter<T>(
      Expression<Func<T, bool>> expr,
      ParameterExpression newParameter)
      {
      var visitor = new ParameterUpdateVisitor(expr.Parameters[0], newParameter);
      var body = visitor.Visit(expr.Body);

      return Expression.Lambda<Func<T, bool>>(body, newParameter);
      }

      [TestMethod]
      public void ExpressionText()
      {
      string text = "test";

      Expression<Func<Coco, bool>> expr1 = p => p.Item1.Contains(text);
      Expression<Func<Coco, bool>> expr2 = q => q.Item2.Contains(text);
      Expression<Func<Coco, bool>> expr3 = UpdateParameter(expr2, expr1.Parameters[0]);

      var expr4 = Expression.Lambda<Func<Recording, bool>>(
      Expression.OrElse(expr1.Body, expr3.Body), expr1.Parameters[0]);

      var func = expr4.Compile();

      Assert.IsTrue(func(new Coco { Item1 = "caca", Item2 = "test pipi" }));
      }





      share|improve this answer














      If you provider does not support Invoke and you need to combine two expression, you can use an ExpressionVisitor to replace the parameter in the second expression by the parameter in the first expression.



      class ParameterUpdateVisitor : ExpressionVisitor
      {
      private ParameterExpression _oldParameter;
      private ParameterExpression _newParameter;

      public ParameterUpdateVisitor(ParameterExpression oldParameter, ParameterExpression newParameter)
      {
      _oldParameter = oldParameter;
      _newParameter = newParameter;
      }

      protected override Expression VisitParameter(ParameterExpression node)
      {
      if (object.ReferenceEquals(node, _oldParameter))
      return _newParameter;

      return base.VisitParameter(node);
      }
      }

      static Expression<Func<T, bool>> UpdateParameter<T>(
      Expression<Func<T, bool>> expr,
      ParameterExpression newParameter)
      {
      var visitor = new ParameterUpdateVisitor(expr.Parameters[0], newParameter);
      var body = visitor.Visit(expr.Body);

      return Expression.Lambda<Func<T, bool>>(body, newParameter);
      }

      [TestMethod]
      public void ExpressionText()
      {
      string text = "test";

      Expression<Func<Coco, bool>> expr1 = p => p.Item1.Contains(text);
      Expression<Func<Coco, bool>> expr2 = q => q.Item2.Contains(text);
      Expression<Func<Coco, bool>> expr3 = UpdateParameter(expr2, expr1.Parameters[0]);

      var expr4 = Expression.Lambda<Func<Recording, bool>>(
      Expression.OrElse(expr1.Body, expr3.Body), expr1.Parameters[0]);

      var func = expr4.Compile();

      Assert.IsTrue(func(new Coco { Item1 = "caca", Item2 = "test pipi" }));
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Dec 13 '12 at 15:18

























      answered Dec 15 '11 at 15:36









      Francis

      2,7371243




      2,7371243








      • 1




        This solved my particular problem where the other solution resulted in the same exception. Thanks.
        – Shaun Wilson
        Mar 7 '13 at 23:49






      • 1




        This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:25














      • 1




        This solved my particular problem where the other solution resulted in the same exception. Thanks.
        – Shaun Wilson
        Mar 7 '13 at 23:49






      • 1




        This is a great solution.
        – Aaron Stainback
        May 13 '14 at 23:25








      1




      1




      This solved my particular problem where the other solution resulted in the same exception. Thanks.
      – Shaun Wilson
      Mar 7 '13 at 23:49




      This solved my particular problem where the other solution resulted in the same exception. Thanks.
      – Shaun Wilson
      Mar 7 '13 at 23:49




      1




      1




      This is a great solution.
      – Aaron Stainback
      May 13 '14 at 23:25




      This is a great solution.
      – Aaron Stainback
      May 13 '14 at 23:25











      0














      I suggest one more improvement to PredicateBuilder and ExpressionVisitor solutions. I called it UnifyParametersByName and you can find it in MIT library of mine: LinqExprHelper. It allows for combining arbitary lambda expressions. Usually the questions are asked about predicate expression, but this idea extends to projection expressions as well.



      The following code employs a method ExprAdres which creates a complicated parametrized expression, using inline lambda. This complicated expression is coded only once, and then reused, thanks to the LinqExprHelper mini-library.



      public IQueryable<UbezpExt> UbezpFull
      {
      get
      {
      System.Linq.Expressions.Expression<
      Func<UBEZPIECZONY, UBEZP_ADRES, UBEZP_ADRES, UbezpExt>> expr =
      (u, parAdrM, parAdrZ) => new UbezpExt
      {
      Ub = u,
      AdrM = parAdrM,
      AdrZ = parAdrZ,
      };

      // From here an expression builder ExprAdres is called.
      var expr2 = expr
      .ReplacePar("parAdrM", ExprAdres("M").Body)
      .ReplacePar("parAdrZ", ExprAdres("Z").Body);
      return UBEZPIECZONY.Select((Expression<Func<UBEZPIECZONY, UbezpExt>>)expr2);
      }
      }


      And this is the subexpression building code:



      public static Expression<Func<UBEZPIECZONY, UBEZP_ADRES>> ExprAdres(string sTyp)
      {
      return u => u.UBEZP_ADRES.Where(a => a.TYP_ADRESU == sTyp)
      .OrderByDescending(a => a.DATAOD).FirstOrDefault();
      }


      What I tried to achieve was to perform parametrized queries without need to copy-paste and with ability to use inline lambdas, which are so pretty. Without all these helper-expression stuff, I would be forced to create whole query in one go.






      share|improve this answer


























        0














        I suggest one more improvement to PredicateBuilder and ExpressionVisitor solutions. I called it UnifyParametersByName and you can find it in MIT library of mine: LinqExprHelper. It allows for combining arbitary lambda expressions. Usually the questions are asked about predicate expression, but this idea extends to projection expressions as well.



        The following code employs a method ExprAdres which creates a complicated parametrized expression, using inline lambda. This complicated expression is coded only once, and then reused, thanks to the LinqExprHelper mini-library.



        public IQueryable<UbezpExt> UbezpFull
        {
        get
        {
        System.Linq.Expressions.Expression<
        Func<UBEZPIECZONY, UBEZP_ADRES, UBEZP_ADRES, UbezpExt>> expr =
        (u, parAdrM, parAdrZ) => new UbezpExt
        {
        Ub = u,
        AdrM = parAdrM,
        AdrZ = parAdrZ,
        };

        // From here an expression builder ExprAdres is called.
        var expr2 = expr
        .ReplacePar("parAdrM", ExprAdres("M").Body)
        .ReplacePar("parAdrZ", ExprAdres("Z").Body);
        return UBEZPIECZONY.Select((Expression<Func<UBEZPIECZONY, UbezpExt>>)expr2);
        }
        }


        And this is the subexpression building code:



        public static Expression<Func<UBEZPIECZONY, UBEZP_ADRES>> ExprAdres(string sTyp)
        {
        return u => u.UBEZP_ADRES.Where(a => a.TYP_ADRESU == sTyp)
        .OrderByDescending(a => a.DATAOD).FirstOrDefault();
        }


        What I tried to achieve was to perform parametrized queries without need to copy-paste and with ability to use inline lambdas, which are so pretty. Without all these helper-expression stuff, I would be forced to create whole query in one go.






        share|improve this answer
























          0












          0








          0






          I suggest one more improvement to PredicateBuilder and ExpressionVisitor solutions. I called it UnifyParametersByName and you can find it in MIT library of mine: LinqExprHelper. It allows for combining arbitary lambda expressions. Usually the questions are asked about predicate expression, but this idea extends to projection expressions as well.



          The following code employs a method ExprAdres which creates a complicated parametrized expression, using inline lambda. This complicated expression is coded only once, and then reused, thanks to the LinqExprHelper mini-library.



          public IQueryable<UbezpExt> UbezpFull
          {
          get
          {
          System.Linq.Expressions.Expression<
          Func<UBEZPIECZONY, UBEZP_ADRES, UBEZP_ADRES, UbezpExt>> expr =
          (u, parAdrM, parAdrZ) => new UbezpExt
          {
          Ub = u,
          AdrM = parAdrM,
          AdrZ = parAdrZ,
          };

          // From here an expression builder ExprAdres is called.
          var expr2 = expr
          .ReplacePar("parAdrM", ExprAdres("M").Body)
          .ReplacePar("parAdrZ", ExprAdres("Z").Body);
          return UBEZPIECZONY.Select((Expression<Func<UBEZPIECZONY, UbezpExt>>)expr2);
          }
          }


          And this is the subexpression building code:



          public static Expression<Func<UBEZPIECZONY, UBEZP_ADRES>> ExprAdres(string sTyp)
          {
          return u => u.UBEZP_ADRES.Where(a => a.TYP_ADRESU == sTyp)
          .OrderByDescending(a => a.DATAOD).FirstOrDefault();
          }


          What I tried to achieve was to perform parametrized queries without need to copy-paste and with ability to use inline lambdas, which are so pretty. Without all these helper-expression stuff, I would be forced to create whole query in one go.






          share|improve this answer












          I suggest one more improvement to PredicateBuilder and ExpressionVisitor solutions. I called it UnifyParametersByName and you can find it in MIT library of mine: LinqExprHelper. It allows for combining arbitary lambda expressions. Usually the questions are asked about predicate expression, but this idea extends to projection expressions as well.



          The following code employs a method ExprAdres which creates a complicated parametrized expression, using inline lambda. This complicated expression is coded only once, and then reused, thanks to the LinqExprHelper mini-library.



          public IQueryable<UbezpExt> UbezpFull
          {
          get
          {
          System.Linq.Expressions.Expression<
          Func<UBEZPIECZONY, UBEZP_ADRES, UBEZP_ADRES, UbezpExt>> expr =
          (u, parAdrM, parAdrZ) => new UbezpExt
          {
          Ub = u,
          AdrM = parAdrM,
          AdrZ = parAdrZ,
          };

          // From here an expression builder ExprAdres is called.
          var expr2 = expr
          .ReplacePar("parAdrM", ExprAdres("M").Body)
          .ReplacePar("parAdrZ", ExprAdres("Z").Body);
          return UBEZPIECZONY.Select((Expression<Func<UBEZPIECZONY, UbezpExt>>)expr2);
          }
          }


          And this is the subexpression building code:



          public static Expression<Func<UBEZPIECZONY, UBEZP_ADRES>> ExprAdres(string sTyp)
          {
          return u => u.UBEZP_ADRES.Where(a => a.TYP_ADRESU == sTyp)
          .OrderByDescending(a => a.DATAOD).FirstOrDefault();
          }


          What I tried to achieve was to perform parametrized queries without need to copy-paste and with ability to use inline lambdas, which are so pretty. Without all these helper-expression stuff, I would be forced to create whole query in one go.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Oct 16 '16 at 20:46









          Jarekczek

          5,01913050




          5,01913050























              0














              I needed to achieve the same results, but using something more generic (as the type was not known). Thanks to marc's answer I finally figured out what I was trying to achieve:



                  public static LambdaExpression CombineOr(Type sourceType, LambdaExpression exp, LambdaExpression newExp) 
              {
              var parameter = Expression.Parameter(sourceType);

              var leftVisitor = new ReplaceExpressionVisitor(exp.Parameters[0], parameter);
              var left = leftVisitor.Visit(exp.Body);

              var rightVisitor = new ReplaceExpressionVisitor(newExp.Parameters[0], parameter);
              var right = rightVisitor.Visit(newExp.Body);

              var delegateType = typeof(Func<,>).MakeGenericType(sourceType, typeof(bool));
              return Expression.Lambda(delegateType, Expression.Or(left, right), parameter);
              }





              share|improve this answer


























                0














                I needed to achieve the same results, but using something more generic (as the type was not known). Thanks to marc's answer I finally figured out what I was trying to achieve:



                    public static LambdaExpression CombineOr(Type sourceType, LambdaExpression exp, LambdaExpression newExp) 
                {
                var parameter = Expression.Parameter(sourceType);

                var leftVisitor = new ReplaceExpressionVisitor(exp.Parameters[0], parameter);
                var left = leftVisitor.Visit(exp.Body);

                var rightVisitor = new ReplaceExpressionVisitor(newExp.Parameters[0], parameter);
                var right = rightVisitor.Visit(newExp.Body);

                var delegateType = typeof(Func<,>).MakeGenericType(sourceType, typeof(bool));
                return Expression.Lambda(delegateType, Expression.Or(left, right), parameter);
                }





                share|improve this answer
























                  0












                  0








                  0






                  I needed to achieve the same results, but using something more generic (as the type was not known). Thanks to marc's answer I finally figured out what I was trying to achieve:



                      public static LambdaExpression CombineOr(Type sourceType, LambdaExpression exp, LambdaExpression newExp) 
                  {
                  var parameter = Expression.Parameter(sourceType);

                  var leftVisitor = new ReplaceExpressionVisitor(exp.Parameters[0], parameter);
                  var left = leftVisitor.Visit(exp.Body);

                  var rightVisitor = new ReplaceExpressionVisitor(newExp.Parameters[0], parameter);
                  var right = rightVisitor.Visit(newExp.Body);

                  var delegateType = typeof(Func<,>).MakeGenericType(sourceType, typeof(bool));
                  return Expression.Lambda(delegateType, Expression.Or(left, right), parameter);
                  }





                  share|improve this answer












                  I needed to achieve the same results, but using something more generic (as the type was not known). Thanks to marc's answer I finally figured out what I was trying to achieve:



                      public static LambdaExpression CombineOr(Type sourceType, LambdaExpression exp, LambdaExpression newExp) 
                  {
                  var parameter = Expression.Parameter(sourceType);

                  var leftVisitor = new ReplaceExpressionVisitor(exp.Parameters[0], parameter);
                  var left = leftVisitor.Visit(exp.Body);

                  var rightVisitor = new ReplaceExpressionVisitor(newExp.Parameters[0], parameter);
                  var right = rightVisitor.Visit(newExp.Body);

                  var delegateType = typeof(Func<,>).MakeGenericType(sourceType, typeof(bool));
                  return Expression.Lambda(delegateType, Expression.Or(left, right), parameter);
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jun 1 '17 at 12:48









                  VorTechS

                  171210




                  171210























                      -7














                      I think this works fine, isn't it ?



                      Func<T, bool> expr1 = (x => x.Att1 == "a");
                      Func<T, bool> expr2 = (x => x.Att2 == "b");
                      Func<T, bool> expr1ANDexpr2 = (x => expr1(x) && expr2(x));
                      Func<T, bool> expr1ORexpr2 = (x => expr1(x) || expr2(x));
                      Func<T, bool> NOTexpr1 = (x => !expr1(x));





                      share|improve this answer

















                      • 1




                        this cannot be used in Linq to SQL for instance
                        – Romain Vergnory
                        May 12 '16 at 9:47
















                      -7














                      I think this works fine, isn't it ?



                      Func<T, bool> expr1 = (x => x.Att1 == "a");
                      Func<T, bool> expr2 = (x => x.Att2 == "b");
                      Func<T, bool> expr1ANDexpr2 = (x => expr1(x) && expr2(x));
                      Func<T, bool> expr1ORexpr2 = (x => expr1(x) || expr2(x));
                      Func<T, bool> NOTexpr1 = (x => !expr1(x));





                      share|improve this answer

















                      • 1




                        this cannot be used in Linq to SQL for instance
                        – Romain Vergnory
                        May 12 '16 at 9:47














                      -7












                      -7








                      -7






                      I think this works fine, isn't it ?



                      Func<T, bool> expr1 = (x => x.Att1 == "a");
                      Func<T, bool> expr2 = (x => x.Att2 == "b");
                      Func<T, bool> expr1ANDexpr2 = (x => expr1(x) && expr2(x));
                      Func<T, bool> expr1ORexpr2 = (x => expr1(x) || expr2(x));
                      Func<T, bool> NOTexpr1 = (x => !expr1(x));





                      share|improve this answer












                      I think this works fine, isn't it ?



                      Func<T, bool> expr1 = (x => x.Att1 == "a");
                      Func<T, bool> expr2 = (x => x.Att2 == "b");
                      Func<T, bool> expr1ANDexpr2 = (x => expr1(x) && expr2(x));
                      Func<T, bool> expr1ORexpr2 = (x => expr1(x) || expr2(x));
                      Func<T, bool> NOTexpr1 = (x => !expr1(x));






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 13 '15 at 15:11









                      Céline

                      11




                      11








                      • 1




                        this cannot be used in Linq to SQL for instance
                        – Romain Vergnory
                        May 12 '16 at 9:47














                      • 1




                        this cannot be used in Linq to SQL for instance
                        – Romain Vergnory
                        May 12 '16 at 9:47








                      1




                      1




                      this cannot be used in Linq to SQL for instance
                      – Romain Vergnory
                      May 12 '16 at 9:47




                      this cannot be used in Linq to SQL for instance
                      – Romain Vergnory
                      May 12 '16 at 9:47


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f457316%2fcombining-two-expressions-expressionfunct-bool%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      MongoDB - Not Authorized To Execute Command

                      in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

                      How to fix TextFormField cause rebuild widget in Flutter