/// <summary> /// 转换 Lambda 表达式中的第一个参数为 <param name="targetElementType"/> 类型。 /// </summary> /// <param name="lambda">需要转换的原始表达式树。</param> /// <param name="targetElementType">需要转换的目标元素类型。</param> /// <returns>转换完成的目标表达式树。</returns> public static LambdaExpression ChangeParameter(this LambdaExpression lambda, Type targetElementType) { var originalParameter = lambda.Parameters[0]; var parameterExpr = Expression.Parameter(targetElementType, originalParameter.Name); var builder = new ExpresionRewriteBuilder(originalParameter.Type, targetElementType); var value = builder.Build(lambda.Body, expr => { if (!(expr is ParameterExpression)) { return(expr); } var pe = expr as ParameterExpression; if (pe.Name == parameterExpr.Name && pe.Type == parameterExpr.Type) { return(parameterExpr); } else { return(expr); } }); var result = Expression.Lambda(value, parameterExpr); return(result); }
/// <summary> /// 为数据源附加查询。 /// </summary> /// <param name="originalElementType">附加查询的原始元素类型。</param> /// <param name="targetExpr">附加查询表达式树。</param> /// <returns>一个附加完成的查询分析器接口。</returns> public IQueryableParser Attach(Type originalElementType, Expression targetExpr) { var builder = new ExpresionRewriteBuilder(originalElementType, DataSource.ElementType); var parser = new QueryableParser { DataSource = DataSource, }; parser.Converter = p => { if (p is UnaryExpression) { p = (p as UnaryExpression).Operand; } if (!(p is LambdaExpression)) { throw new NotSupportedException(); } var lambda = p as LambdaExpression; var @parameters = lambda.Parameters.Where(r => r.Type == builder.SourceType).ToArray(); if ([email protected]()) { return(p); } if (@parameters.Count() > 1) { throw new NotSupportedException(); } var parameterExpr = Expression.Parameter(DataSource.ElementType, @parameters[0].Name); var value = builder.Build(lambda.Body, expr => { if (!(expr is ParameterExpression)) { return(expr); } var pe = expr as ParameterExpression; if (pe.Name == parameterExpr.Name && pe.Type == parameterExpr.Type) { return(parameterExpr); } else { return(expr); } }); var result = Expression.Lambda(value, parameterExpr); return(result); }; parser.Build(targetExpr as MethodCallExpression); return(parser); }