-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathExpressionVisitor.cs
83 lines (73 loc) · 2.46 KB
/
ExpressionVisitor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
using System;
using System.Linq;
using System.Linq.Expressions;
namespace BTR.Core.Linq
{
public static class ExpressionExtensions
{
public static Expression Visit<T>(
this Expression exp,
Func<T, Expression> visitor,
bool visitReplacement = true ) where T : Expression
{
return ExpressionVisitor<T>.Visit( exp, visitor, visitReplacement );
}
public static TExp Visit<T, TExp>(
this TExp exp,
Func<T, Expression> visitor,
bool visitReplacement = true )
where T : Expression
where TExp : Expression
{
return (TExp)ExpressionVisitor<T>.Visit( exp, visitor, visitReplacement );
}
public static Expression<TDelegate> Visit<T, TDelegate>(
this Expression<TDelegate> exp,
Func<T, Expression> visitor,
bool visitReplacement = true ) where T : Expression
{
return ExpressionVisitor<T>.Visit<TDelegate>( exp, visitor, visitReplacement );
}
public static IQueryable<TSource> Visit<T, TSource>(
this IQueryable<TSource> source,
Func<T, Expression> visitor,
bool visitReplacement = true ) where T : Expression
{
return source.Provider.CreateQuery<TSource>( ExpressionVisitor<T>.Visit( source.Expression, visitor, visitReplacement ) );
}
}
/// <summary>
/// This class visits every Parameter expression in an expression tree and calls a delegate
/// to optionally replace the parameter. This is useful where two expression trees need to
/// be merged (and they don't share the same ParameterExpressions).
/// </summary>
public class ExpressionVisitor<T> : ExpressionVisitor where T : Expression
{
private Func<T, Expression> visitor;
private bool visitReplacement;
public ExpressionVisitor( Func<T, Expression> visitor, bool visitReplacement = true )
{
this.visitor = visitor;
this.visitReplacement = visitReplacement;
}
public static Expression Visit(
Expression exp,
Func<T, Expression> visitor,
bool visitReplacement = true )
{
return new ExpressionVisitor<T>( visitor, visitReplacement ).Visit( exp );
}
public static Expression<TDelegate> Visit<TDelegate>(
Expression<TDelegate> exp,
Func<T, Expression> visitor,
bool visitReplacement = true )
{
return (Expression<TDelegate>)new ExpressionVisitor<T>( visitor, visitReplacement ).Visit( exp );
}
public override Expression Visit( Expression exp )
{
var result = ( exp is T && visitor != null ) ? visitor( (T)exp ) : exp;
return ( result != exp && !visitReplacement ) ? result : base.Visit( result );
}
}
}