using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using VolPro.Core.BaseProvider;
using VolPro.Core.Const;
using VolPro.Core.Enums;
namespace VolPro.Core.Extensions
{
public static class LambdaExtensions
{
///
/// 分页查询
///
///
///
///
///
///
public static ISugarQueryable TakePage(this ISugarQueryable queryable, int page, int size = 15)
{
return queryable.TakeOrderByPage(page, size);
}
///
/// 分页查询
///
///
///
///
///
///
///
public static ISugarQueryable TakeOrderByPage(this ISugarQueryable queryable, int page, int size = 15, Expression>> orderBy = null)
{
if (page <= 0)
{
page = 1;
}
return queryable.GetISugarQueryableOrderBy(orderBy.GetExpressionToDic())
.Skip((page - 1) * size)
.Take(size);
}
public static IEnumerable TakePage(this List list, int page, int size = 15)
{
if (page <= 0)
{
page = 1;
}
return list.Skip((page - 1) * size).Take(size);
}
///
/// 创建lambda表达式:p=>true
///
///
///
public static Expression> True()
{
return p => true;
}
///
/// 创建lambda表达式:p=>false
///
///
///
public static Expression> False()
{
return p => false;
}
public static ParameterExpression GetExpressionParameter(this Type type)
{
return Expression.Parameter(type, "p");
}
///
/// 创建lambda表达式:p=>p.propertyName
///
///
///
///
///
public static Expression> GetExpression(this string propertyName)
{
return propertyName.GetExpression(typeof(T).GetExpressionParameter());
}
///
/// 创建委托有返回值的表达式:p=>p.propertyName
///
///
///
///
///
public static Func GetFun(this string propertyName)
{
return propertyName.GetExpression(typeof(T).GetExpressionParameter()).Compile();
}
///
/// 创建lambda表达式:p=>false
/// 在已知TKey字段类型时,如动态排序OrderBy(x=>x.ID)会用到此功能,返回的就是x=>x.ID
/// Expression> expression = x => x.CreateDate;指定了类型
///
///
///
public static Expression> GetExpression(this string propertyName, ParameterExpression parameter)
{
if (typeof(TKey).Name == "Object")
return Expression.Lambda>(Expression.Convert(Expression.Property(parameter, propertyName), typeof(object)), parameter);
return Expression.Lambda>(Expression.Property(parameter, propertyName), parameter);
}
///
/// 创建lambda表达式:p=>false
/// object不能确认字段类型(datetime,int,string),如动态排序OrderBy(x=>x.ID)会用到此功能,返回的就是x=>x.ID
/// Expression> expression = x => x.CreateDate;任意类型的字段
///
///
///
public static Expression> GetExpression(this string propertyName)
{
return propertyName.GetExpression(typeof(T).GetExpressionParameter());
}
public static Expression> GetExpression(this string propertyName, ParameterExpression parameter)
{
return Expression.Lambda>(Expression.Convert(Expression.Property(parameter, propertyName), typeof(object)), parameter);
}
///
///
///
///
/// 字段名
/// 表达式的值
/// 创建表达式的类型,如:p=>p.propertyName != propertyValue
/// p=>p.propertyName.Contains(propertyValue)
///
///
///
///
///
/// 字段名
/// 表达式的值
/// 创建表达式的类型,如:p=>p.propertyName != propertyValue
/// p=>p.propertyName.Contains(propertyValue)
///
public static Expression> CreateExpression(this string propertyName, object propertyValue, LinqExpressionType expressionType, bool checkNullProperty = false)
{
return propertyName.CreateExpression(propertyValue, null, expressionType, checkNullProperty);
}
private static Expression> GetContainsExpression(string propertyName, object propertyValue, ParameterExpression parameter, LinqExpressionType expressionType)
{
Type proType = typeof(T).GetProperty(propertyName).PropertyType;
var list = propertyValue as System.Collections.IList;
List arr = new List();
foreach (var value in list)
{
if (value == null || value.ToString().Trim() == "")
{
continue;
}
var valRes = (proType == typeof(string) ? value.ToString() : value).ChangeType(proType);
if (valRes != null)
{
arr.Add((FieldType)valRes);
}
}
//string 类型的字段,如果值带有'单引号,EF会默认变成''两个单引号
var method = arr.GetType().GetMethod("Contains");
ConstantExpression constantCollection = Expression.Constant(arr);
MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName);
if (expressionType == LinqExpressionType.NotIn)
{
return Expression.Lambda>(Expression.Not(Expression.Call(constantCollection, method, memberProperty)), parameter);
}
else
{
MethodCallExpression methodCall = Expression.Call(constantCollection, method, memberProperty);
return Expression.Lambda>(methodCall, parameter);
}
}
public static bool CheckFilterNullExpression(this LinqExpressionType filterType)
{
switch (filterType)
{
case LinqExpressionType.Empty:
case LinqExpressionType.NotEmpty:
case LinqExpressionType.Null:
case LinqExpressionType.NotNull:
case LinqExpressionType.NullOrEmpty:
case LinqExpressionType.NotNullOrEmpty:
return true;
}
return false;
}
// 核心:创建与目标类型兼容的null常量表达式
private static ConstantExpression CreateNullConstant(Type targetType)
{
if (!targetType.IsValueType)
{
return Expression.Constant(null, targetType);
}
if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// 可空类型的null常量需用默认值(底层类型为null)
return Expression.Constant(null, targetType);
}
throw new InvalidOperationException($"非可空值类型 {targetType} 不支持null常量");
}
///
/// 根据条件类型生成相应的查询表达式
///
/// 实体类型
/// 属性名称
/// 条件类型
/// 生成的查询表达式
public static Expression> GenerateEmptyCondition(
string propertyName,
LinqExpressionType conditionType)
{
// 获取属性信息并验证
PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName);
Type propertyType = propertyInfo.PropertyType;
// 检查字符串专属条件是否应用在字符串属性上
bool isStringCondition =
conditionType == LinqExpressionType.Empty ||
conditionType == LinqExpressionType.NotEmpty ||
conditionType == LinqExpressionType.NotNullOrEmpty;
if (isStringCondition && propertyType != typeof(string))
{
throw new InvalidOperationException(
$"条件类型 {conditionType} 仅适用于字符串类型的属性,不能用于 {propertyType} 类型");
}
// 创建参数表达式 (x => ... 中的 x)
ParameterExpression parameter = Expression.Parameter(typeof(T), "x");
// 创建属性访问表达式 (x.PropertyName)
MemberExpression property = Expression.Property(parameter, propertyInfo);
Expression conditionExpression;
switch (conditionType)
{
case LinqExpressionType.Empty:
// x.PropertyName == "" (仅适用于字符串)
conditionExpression = Expression.Equal(
property,
Expression.Constant("", typeof(string))
);
break;
case LinqExpressionType.Null:
// x.PropertyName == null
if (typeof(string) == propertyType)
{
conditionExpression = Expression.Equal(
property,
Expression.Constant(null, propertyType.IsValueType ? typeof(object) : propertyType)
);
}
else
{
conditionExpression = Expression.Equal(property, CreateNullConstant(propertyType));
}
break;
case LinqExpressionType.NotEmpty:
case LinqExpressionType.NotNullOrEmpty:
// x.PropertyName != "" (仅适用于字符串)
var notNull = Expression.NotEqual(property, Expression.Constant(null, typeof(string)));
var notEmpty = Expression.NotEqual(property, Expression.Constant("", typeof(string)));
conditionExpression = Expression.AndAlso(notNull, notEmpty);
break;
case LinqExpressionType.NotNull:
// x.PropertyName != null
if (typeof(string) == propertyType)
{
conditionExpression = Expression.NotEqual(
property,
Expression.Constant(null, propertyType.IsValueType ? typeof(object) : propertyType)
);
}
else
{
conditionExpression = Expression.NotEqual(property, CreateNullConstant(propertyType));
}
break;
case LinqExpressionType.NullOrEmpty:
// !string.IsNullOrEmpty(x.PropertyName) (仅适用于字符串)
var isNull = Expression.Equal(property, Expression.Constant(null, typeof(string)));
var isEmpty = Expression.Equal(property, Expression.Constant("", typeof(string)));
conditionExpression = Expression.OrElse(isNull, isEmpty);
break;
default:
throw new ArgumentOutOfRangeException(
nameof(conditionType),
"不支持的条件类型"
);
}
// 创建并返回lambda表达式
return Expression.Lambda>(conditionExpression, parameter);
}
///
///
///
///
/// 字段名
/// 表达式的值
/// 创建表达式的类型,如:p=>p.propertyName != propertyValue
/// p=>p.propertyName.Contains(propertyValue)
///
private static Expression> CreateExpression(
this string propertyName,
object propertyValue,
ParameterExpression parameter,
LinqExpressionType expressionType,
bool checkNullProperty = false)
{
Type proType = typeof(T).GetProperty(propertyName).PropertyType;
//空或者null查询
if (expressionType.CheckFilterNullExpression())
{
return GenerateEmptyCondition(propertyName, expressionType);
}
if (checkNullProperty)
{
if (propertyValue == null)
{
return True();
}
if (!(proType == typeof(string) || proType == typeof(int?) || proType == typeof(long?) || proType == typeof(decimal?) || proType == typeof(float?) || proType == typeof(bool?) || proType == typeof(DateTime?)))
{
checkNullProperty = false;
}
}
//创建节点变量如p=>的节点p
// parameter ??= Expression.Parameter(typeof(T), "p");//创建参数p
parameter = parameter ?? Expression.Parameter(typeof(T), "p");
Expression> expression = null;
//创建节点的属性p=>p.name 属性name
MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName);
if (expressionType == LinqExpressionType.In || expressionType == LinqExpressionType.NotIn)
{
if (!(propertyValue is System.Collections.IList list) || list.Count == 0) return x => false;
var res = typeof(LambdaExtensions).GetMethod("GetContainsExpression", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(new Type[] { typeof(T), proType })
.Invoke(null, new object[] { propertyName, propertyValue, parameter, expressionType }) as Expression>;
return res;
}
// object value = propertyValue;
ConstantExpression constant = proType == typeof(string)
? Expression.Constant(propertyValue) : Expression.Constant(propertyValue.ToString().ChangeType(proType));
// DateTime只选择了日期的时候自动在结束日期加一天,修复DateTime类型使用日期区间查询无法查询到结束日期的问题
if ((proType == typeof(DateTime) || proType == typeof(DateTime?)) && expressionType == LinqExpressionType.LessThanOrEqual && propertyValue.ToString().Length == 10)
{
expressionType = LinqExpressionType.LessThan;
constant = Expression.Constant(Convert.ToDateTime(propertyValue.ToString()).AddDays(1));
}
if (checkNullProperty)
{
expression = CreateHasValueCondition(proType, parameter, propertyName, propertyValue, constant, expressionType);
if (expression != null)
{
return expression;
}
}
UnaryExpression member = Expression.Convert(memberProperty, constant.Type);
switch (expressionType)
{
////p=>p.propertyName == propertyValue
//case LinqExpressionType.Equal:
// expression = Expression.Lambda>(Expression.Equal(member, constant), parameter);
// break;
//p=>p.propertyName != propertyValue
case LinqExpressionType.NotEqual:
expression = Expression.Lambda>(Expression.NotEqual(member, constant), parameter);
break;
// p => p.propertyName > propertyValue
case LinqExpressionType.GreaterThan:
expression = Expression.Lambda>(Expression.GreaterThan(member, constant), parameter);
break;
// p => p.propertyName < propertyValue
case LinqExpressionType.LessThan:
expression = Expression.Lambda>(Expression.LessThan(member, constant), parameter);
break;
// p => p.propertyName >= propertyValue
case LinqExpressionType.ThanOrEqual:
expression = Expression.Lambda>(Expression.GreaterThanOrEqual(member, constant), parameter);
break;
// p => p.propertyName <= propertyValue
case LinqExpressionType.LessThanOrEqual:
expression = Expression.Lambda>(Expression.LessThanOrEqual(member, constant), parameter);
break;
// p => p.propertyName.Contains(propertyValue)
// p => !p.propertyName.Contains(propertyValue)
case LinqExpressionType.Like:
case LinqExpressionType.NotLike:
case LinqExpressionType.Contains:
case LinqExpressionType.NotContains:
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
constant = Expression.Constant(propertyValue, typeof(string));
if (expressionType == LinqExpressionType.Like || expressionType == LinqExpressionType.Contains)
{
expression = Expression.Lambda>(Expression.Call(member, method, constant), parameter);
}
else
{
expression = Expression.Lambda>(Expression.Not(Expression.Call(member, method, constant)), parameter);
}
break;
case LinqExpressionType.LikeStart:
case LinqExpressionType.LikeEnd:
string m = expressionType == LinqExpressionType.LikeStart ? "StartsWith" : "EndsWith";
var startsWithMethod = typeof(string).GetMethod(m, new[] { typeof(string) });
var searchTermConstant = Expression.Constant(propertyValue, typeof(string));
var startsWithCall = Expression.Call(member, startsWithMethod, searchTermConstant);
expression = Expression.Lambda>(startsWithCall, parameter);
break;
default:
expression = Expression.Lambda>(Expression.Equal(member, constant), parameter);
break;
// break;
}
return expression;
}
private static Expression> CreateHasValueCondition(
Type proType,
ParameterExpression parameter,
string propertyName,
object propertyValue,
ConstantExpression constant,
LinqExpressionType expressionType
)
{
BinaryExpression condition = null;
var property = Expression.Property(parameter, propertyName);
if (proType == typeof(string))
{
Expression binaryExpression = null;
switch (expressionType)
{
case LinqExpressionType.Like:
case LinqExpressionType.Contains:
binaryExpression = Expression.Call(property, "Contains", null, constant);
break;
case LinqExpressionType.LikeStart:
binaryExpression = Expression.Call(property, "StartsWith", null, constant);
break;
case LinqExpressionType.LikeEnd:
binaryExpression = Expression.Call(property, "EndsWith", null, constant);
break;
case LinqExpressionType.NotLike:
case LinqExpressionType.NotContains:
binaryExpression = Expression.Not(Expression.Call(property, "Contains", null, constant));
break;
case LinqExpressionType.NotEqual:
binaryExpression = Expression.Not(Expression.Equal(property, constant));
break;
default:
binaryExpression = Expression.Equal(property, constant);
break;
}
var stringCondition = Expression.Condition(
Expression.Equal(property, Expression.Constant(null)), // 如果 Charlie 为 null
Expression.Constant(false), // 返回 false
binaryExpression // 否则比较值
);
var stringExpression = Expression.Lambda>(stringCondition, parameter);
return stringExpression;
}
var hasValue = Expression.Property(property, "HasValue"); // 判断 字段 是否有值
var value = Expression.Property(property, "Value"); // 获取 字段 的值
switch (expressionType)
{
case LinqExpressionType.NotEqual:
condition = Expression.NotEqual(value, constant);
break;
// p => p.propertyName > propertyValue
case LinqExpressionType.GreaterThan:
condition = Expression.GreaterThan(value, constant);
break;
// p => p.propertyName < propertyValue
case LinqExpressionType.LessThan:
condition = Expression.LessThan(value, constant);
break;
case LinqExpressionType.LessThanOrEqual:
condition = Expression.LessThanOrEqual(value, constant);
break;
// p => p.propertyName >= propertyValue
case LinqExpressionType.ThanOrEqual:
condition = Expression.GreaterThanOrEqual(value, constant);
break;
case LinqExpressionType.Equal:
condition = Expression.Equal(value, constant); // 构建条件:xx==
break;
}
if (condition == null)
{
return null;
}
var body = Expression.Condition(hasValue, condition, Expression.Constant(false)); // 构建条件体
var expression = Expression.Lambda>(body, parameter);
return expression;
}
///
/// 表达式转换成KeyValList(主要用于多字段排序,并且多个字段的排序规则不一样)
/// 如有多个字段进行排序,参数格式为
/// Expression>> orderBy = x => new Dictionary
///
///
///
public static IEnumerable> GetExpressionToPair(this Expression>> expression)
{
foreach (var exp in ((ListInitExpression)expression.Body).Initializers)
{
yield return new KeyValuePair(
exp.Arguments[0] is MemberExpression ?
(exp.Arguments[0] as MemberExpression).Member.Name.ToString()
: ((exp.Arguments[0] as UnaryExpression).Operand as MemberExpression).Member.Name,
(QueryOrderBy)(
exp.Arguments[1] as ConstantExpression != null
? (exp.Arguments[1] as ConstantExpression).Value
//2021.07.04增加自定排序按条件表达式
: Expression.Lambda>(exp.Arguments[1] as Expression).Compile()()
));
}
}
///
/// 表达式转换成KeyValList(主要用于多字段排序,并且多个字段的排序规则不一样)
/// 如有多个字段进行排序,参数格式为
/// Expression>> orderBy = x => new Dictionary() {
/// { x.ID, QueryOrderBy.Desc },
/// { x.DestWarehouseName, QueryOrderBy.Asc }
/// };
/// 返回的是new Dictionary(){{}}key为排序字段,QueryOrderBy为排序方式
///
///
///
///
public static Dictionary GetExpressionToDic(this Expression>> expression)
{
//2020.09.14增加排序字段null值判断
if (expression == null)
{
return new Dictionary();
}
return expression.GetExpressionToPair().ToList().ToDictionary(x => x.Key, x => x.Value);
}
///
/// 解析多字段排序
///
///
///
/// string=排序的字段,bool=true降序/false升序
///
public static ISugarQueryable GetISugarQueryableOrderBy(this ISugarQueryable queryable, Dictionary orderBySelector)
{
string[] orderByKeys = orderBySelector.Select(x => x.Key).ToArray();
if (orderByKeys == null || orderByKeys.Length == 0) return queryable;
ISugarQueryable queryableOrderBy = null;
// string orderByKey = orderByKeys[^1];
string orderByKey = orderByKeys[0];
queryableOrderBy = orderBySelector[orderByKey] == QueryOrderBy.Desc
? queryableOrderBy = queryable.OrderByDescending(orderByKey.GetExpression())
: queryable.OrderBy(orderByKey.GetExpression());
for (int i = 1; i < orderByKeys.Length; i++)
{
queryableOrderBy = orderBySelector[orderByKeys[i]] == QueryOrderBy.Desc
? queryableOrderBy.OrderByDescending(orderByKeys[i].GetExpression())
: queryableOrderBy.OrderBy(orderByKeys[i].GetExpression());
}
return queryableOrderBy;
}
///
/// 获取对象表达式指定属性的值
/// 如获取:Out_Scheduling对象的ID或基他字段
///
///
/// 格式 Expression>sch=x=>new {x.v1,x.v2} or x=>x.v1 解析里面的值返回为数组
///
public static string[] GetExpressionToArray(this Expression> expression)
{
string[] propertyNames = null;
if (expression.Body is MemberExpression)
{
propertyNames = new string[] { ((MemberExpression)expression.Body).Member.Name };
}
else
{
propertyNames = expression.GetExpressionProperty().Distinct().ToArray();
}
return propertyNames;
}
///
/// 与下面and生成方式有所不同,如果直接用表达式1.2进行合并产会提示数据源不同的异常,只能使用下面的的and合并
/// 此种合并是在使用的同一个数据源(变量),生成的sql语句同样有性能问题(本身可以索引扫描的,生成的sql语句的case when变成索引查找)
///
/// 通过字段动态生成where and /or表达
/// 如:有多个where条件,当条件成立时where 1=1 and/or 2=2,依次往后拼接
///
///
///
/// ExpressionParameters
/// 1、Field生成的字段
/// 2、ExpressionType 表达式类型大于、小于、于大=、小于=、contains
/// 3、Value表达式的值
///
///
public static Expression> And(List listExpress)
{
return listExpress.Compose(Expression.AndAlso);
}
///
/// 同上面and用法相同
///
///
///
///
public static Expression> Or(this List listExpress)
{
return listExpress.Compose(Expression.OrElse);
}
private static Expression> Compose(this List listExpress, Func merge)
{
ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
Expression> expression = null;
foreach (ExpressionParameters exp in listExpress)
{
if (expression == null)
{
expression = exp.Field.GetExpression(parameter);
}
else
{
expression = expression.Compose(exp.Field.GetExpression(parameter), merge);
}
}
return expression;
}
///
/// https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/
/// 表达式合并(合并生产的sql语句有性能问题)
/// 合并两个where条件,如:多个查询条件时,判断条件成立才where
///
///
///
///
///
public static Expression> And(this Expression> first, Expression> second)
{
return first.Compose(second, Expression.AndAlso);
}
public static Expression> Or(this Expression> first, Expression> second)
{
return first.Compose(second, Expression.OrElse);
}
public static Expression Compose(this Expression first, Expression second, Func merge)
{
// build parameter map (from parameters of second to parameters of first)
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
// replace parameters in the second lambda expression with parameters from the first
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
// apply composition of lambda expression bodies to parameters from the first expression
return Expression.Lambda(merge(first.Body, secondBody), first.Parameters);
}
public static ISugarQueryable GetQueryableSelect(this ISugarQueryable queryable)
{
Expression> expression = CreateMemberInitExpression();
return queryable.Select(expression);
}
///
/// 动态创建表达式Expression> expression = CreateMemberInitExpression();
///结果为Expression> expression1 = x => new User() { Age = x.Age, Species = x.Species };
///参照文档https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.memberinitexpression?redirectedfrom=MSDN&view=netframework-4.8
///
///
///
///
public static Expression> CreateMemberInitExpression(Type resultType = null)
{
resultType = resultType ?? typeof(Result);
ParameterExpression left = Expression.Parameter(typeof(Source), "p");
NewExpression newExpression = Expression.New(resultType);
PropertyInfo[] propertyInfos = resultType.GetProperties();
List memberBindings = new List();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
MemberExpression member = Expression.Property(left, propertyInfo.Name);
MemberBinding speciesMemberBinding = Expression.Bind(resultType.GetMember(propertyInfo.Name)[0], member);
memberBindings.Add(speciesMemberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(newExpression, memberBindings);
Expression> expression = Expression.Lambda>(memberInitExpression, new ParameterExpression[] { left });
return expression;
}
public static Expression> CreateMemberInitExpression(Type resultType)
{
return CreateMemberInitExpression(resultType);
}
///
/// 属性判断待完
///
///
///
public static IEnumerable GetGenericProperties(this Type type)
{
return type.GetProperties().GetGenericProperties();
}
///
/// 属性判断待完
///
///
///
public static IEnumerable GetGenericProperties(this IEnumerable properties)
{
return properties.Where(x => !x.PropertyType.IsGenericType && x.PropertyType.GetInterface("IList") == null || x.PropertyType.GetInterface("IEnumerable", false) == null);
}
public static string GetDbCondition(this string stringType)
{
string reslut = null;
switch (stringType?.ToLower())
{
case HtmlElementType.droplist:
case HtmlElementType.selectlist:
case HtmlElementType.textarea:
case HtmlElementType.checkbox:
reslut = HtmlElementType.Contains;
break;
case HtmlElementType.thanorequal:
reslut = HtmlElementType.ThanOrEqual;
break;
case HtmlElementType.lessorequal:
reslut = HtmlElementType.LessOrequal;
break;
case HtmlElementType.gt:
reslut = HtmlElementType.GT;
break;
case HtmlElementType.lt:
reslut = HtmlElementType.lt;
break;
case HtmlElementType.like:
reslut = HtmlElementType.like;
break;
case HtmlElementType.NotEqual:
reslut = HtmlElementType.NotEqual;
break;
default:
reslut = HtmlElementType.Equal;
break;
}
return reslut;
}
}
public class ExpressionParameters
{
public string Field { get; set; }
public LinqExpressionType ExpressionType { get; set; }
public object Value { get; set; }
// public
}
public class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary map;
public ParameterRebinder(Dictionary map)
{
this.map = map ?? new Dictionary();
}
public static Expression ReplaceParameters(Dictionary map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression replacement;
if (map.TryGetValue(p, out replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}
}