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); }
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; }
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); }
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); }