Combining two expressions (Expression<Func>)
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
add a comment |
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
7
Very useful post I got from Google: LINQ to Entities: Combining Predicates
– Thomas C. G. de Vilhena
Jan 1 '14 at 18:23
add a comment |
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
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
c# linq lambda expression
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
add a comment |
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
add a comment |
7 Answers
7
active
oldest
votes
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);
}
}
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
|
show 16 more comments
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;
}
}
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
|
show 1 more comment
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.
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
|
show 3 more comments
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" }));
}
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
add a comment |
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.
add a comment |
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);
}
add a comment |
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));
1
this cannot be used in Linq to SQL for instance
– Romain Vergnory
May 12 '16 at 9:47
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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);
}
}
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
|
show 16 more comments
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);
}
}
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
|
show 16 more comments
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);
}
}
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);
}
}
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
|
show 16 more comments
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
|
show 16 more comments
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;
}
}
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
|
show 1 more comment
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;
}
}
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
|
show 1 more comment
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;
}
}
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;
}
}
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
|
show 1 more comment
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
|
show 1 more comment
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.
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
|
show 3 more comments
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.
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
|
show 3 more comments
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.
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.
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
|
show 3 more comments
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
|
show 3 more comments
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" }));
}
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
add a comment |
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" }));
}
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
add a comment |
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" }));
}
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" }));
}
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
add a comment |
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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Oct 16 '16 at 20:46
Jarekczek
5,01913050
5,01913050
add a comment |
add a comment |
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);
}
add a comment |
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);
}
add a comment |
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);
}
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);
}
answered Jun 1 '17 at 12:48
VorTechS
171210
171210
add a comment |
add a comment |
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));
1
this cannot be used in Linq to SQL for instance
– Romain Vergnory
May 12 '16 at 9:47
add a comment |
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));
1
this cannot be used in Linq to SQL for instance
– Romain Vergnory
May 12 '16 at 9:47
add a comment |
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));
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));
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
7
Very useful post I got from Google: LINQ to Entities: Combining Predicates
– Thomas C. G. de Vilhena
Jan 1 '14 at 18:23