Example #1
0
        protected override SequenceConvertInfo Convert(
            ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
        {
            if (methodCall.Arguments.Count == 2)
            {
                var predicate = (LambdaExpression)methodCall.Arguments[1].Unwrap();
                var info      = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), predicate.Parameters[0]);

                if (info != null)
                {
                    info.Expression = methodCall.Transform(ex => ConvertMethod(methodCall, 0, info, predicate.Parameters[0], ex));
                    info.Parameter  = param;

                    return(info);
                }
            }
            else
            {
                var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), null);

                if (info != null)
                {
                    info.Expression = methodCall.Transform(ex => ConvertMethod(methodCall, 0, info, null, ex));
                    info.Parameter  = param;

                    return(info);
                }
            }

            return(null);
        }
Example #2
0
		protected override SequenceConvertInfo Convert(
			ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
		{
			var predicate = (LambdaExpression)methodCall.Arguments[1].Unwrap();
			var info      = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), predicate.Parameters[0]);

			if (info != null)
			{
				info.Expression = methodCall.Transform(ex => ConvertMethod(methodCall, 0, info, predicate.Parameters[0], ex));

				if (param != null)
				{
					if (param.Type != info.Parameter.Type)
						param = Expression.Parameter(info.Parameter.Type, param.Name);

					if (info.ExpressionsToReplace != null)
						foreach (var path in info.ExpressionsToReplace)
						{
							path.Path = path.Path.Transform(e => e == info.Parameter ? param : e);
							path.Expr = path.Expr.Transform(e => e == info.Parameter ? param : e);
						}
				}

				info.Parameter = param;

				return info;
			}

			return null;
		}
Example #3
0
        protected override SequenceConvertInfo Convert(
            ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
        {
            var info = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), null);

            if (info != null)
            {
                info.Expression =
                    Expression.Call(
                        methodCall.Method.DeclaringType,
                        methodCall.Method.Name,
                        new[] { info.Expression.Type.GetGenericArgumentsEx()[0] },
                        info.Expression, methodCall.Arguments[1]);
                //methodCall.Transform(ex => ConvertMethod(methodCall, 0, info, null, ex));
                info.Parameter = param;

                return(info);
            }

            return(null);
        }
Example #4
0
        protected override SequenceConvertInfo Convert(
            ExpressionBuilder builder, MethodCallExpression originalMethodCall, BuildInfo buildInfo, ParameterExpression param)
        {
            var methodCall = originalMethodCall;
            var selector   = (LambdaExpression)methodCall.Arguments[1].Unwrap();
            var info       = builder.ConvertSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]), selector.Parameters[0]);

            if (info != null)
            {
                methodCall = (MethodCallExpression)methodCall.Transform(
                    ex => ConvertMethod(methodCall, 0, info, selector.Parameters[0], ex));
                selector = (LambdaExpression)methodCall.Arguments[1].Unwrap();
            }

            if (param != null && !ReferenceEquals(param, builder.SequenceParameter))
            {
                var list =
                    (
                        from path in GetExpressions(selector.Parameters[0], param, 0, selector.Body.Unwrap())
                        orderby path.Level descending
                        select path
                    ).ToList();

                if (list.Count > 0)
                {
                    var plist = list.Where(e => ReferenceEquals(e.Expr, selector.Parameters[0])).ToList();

                    if (plist.Count > 1)
                    {
                        list = list.Except(plist.Skip(1)).ToList();
                    }

                    var p = plist.FirstOrDefault();

                    if (p == null)
                    {
                        var types  = methodCall.Method.GetGenericArguments();
                        var mgen   = methodCall.Method.GetGenericMethodDefinition();
                        var btype  = typeof(ExpressionHoder <,>).MakeGenericType(types[0], selector.Body.Type);
                        var fields = btype.GetFieldsEx();
                        var pold   = selector.Parameters[0];
                        var psel   = Expression.Parameter(types[0], pold.Name);

                        methodCall = Expression.Call(
                            methodCall.Object,
                            mgen.MakeGenericMethod(types[0], btype),
                            methodCall.Arguments[0],
                            Expression.Lambda(
                                Expression.MemberInit(
                                    Expression.New(btype),
                                    Expression.Bind(fields[0], psel),
                                    Expression.Bind(fields[1], selector.Body.Transform(e => e == pold ? psel : e))),
                                psel));

                        selector = (LambdaExpression)methodCall.Arguments[1].Unwrap();
                        param    = Expression.Parameter(selector.Body.Type, param.Name);

                        list.Add(new SequenceConvertPath {
                            Path = param, Expr = Expression.MakeMemberAccess(param, fields[1]), Level = 1
                        });

                        var expr = Expression.MakeMemberAccess(param, fields[0]);

                        foreach (var t in list)
                        {
                            t.Expr = t.Expr.Transform(ex => ReferenceEquals(ex, pold) ? expr : ex);
                        }

                        return(new SequenceConvertInfo
                        {
                            Parameter = param,
                            Expression = methodCall,
                            ExpressionsToReplace = list
                        });
                    }

                    if (info != null)
                    {
                        if (info.ExpressionsToReplace != null)
                        {
                            foreach (var path in info.ExpressionsToReplace)
                            {
                                path.Path   = path.Path.Transform(e => ReferenceEquals(e, info.Parameter) ? p.Path : e);
                                path.Expr   = path.Expr.Transform(e => ReferenceEquals(e, info.Parameter) ? p.Path : e);
                                path.Level += p.Level;

                                list.Add(path);
                            }

                            list = list.OrderByDescending(path => path.Level).ToList();
                        }
                    }

                    if (list.Count > 1)
                    {
                        return(new SequenceConvertInfo
                        {
                            Parameter = param,
                            Expression = methodCall,
                            ExpressionsToReplace = list
                                                   .Where(e => !ReferenceEquals(e, p))
                                                   .Select(ei =>
                            {
                                ei.Expr = ei.Expr.Transform(e => ReferenceEquals(e, p.Expr) ? p.Path : e);
                                return ei;
                            })
                                                   .ToList()
                        });
                    }
                }
            }

            if (!ReferenceEquals(methodCall, originalMethodCall))
            {
                return new SequenceConvertInfo
                       {
                           Parameter  = param,
                           Expression = methodCall,
                       }
            }
            ;

            return(null);
        }