Exemple #1
0
        /// <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);
        }