protected override Expression VisitMethodCall(MethodCallExpression node) { var declaringType = node.Method.DeclaringType; if (declaringType == typeof(System.Linq.Enumerable) || declaringType == typeof(Queryable) || (declaringType.IsGenericType && declaringType.GetGenericTypeDefinition() == typeof(IQueryable <>))) { var provider = QueryProviderFinder.FindProvider(node); if (provider != null) { var value = provider.Execute(node); PushValue(value); return(node); } } var argValues = new object[node.Arguments.Count]; for (var i = 0; i < node.Arguments.Count; i++) { var arg = node.Arguments[i]; if (arg.NodeType == ExpressionType.Lambda) { var exp = ((LambdaExpression)arg); Debug.Assert(exp.Parameters.Count == 1); MethodInfo m; var bf = BindingFlags.Static | BindingFlags.NonPublic; var list = exp.Parameters.Select(o => o.Type).ToList(); list.Add(exp.Body.Type); var types = list.ToArray(); switch (exp.Parameters.Count) { case 1: m = this.GetType().GetMethod("CreateFunc1", bf) .MakeGenericMethod(types); break; case 2: m = this.GetType().GetMethod("CreateFunc2", bf) .MakeGenericMethod(types); break; case 3: m = this.GetType().GetMethod("CreateFunc3", bf) .MakeGenericMethod(types); break; default: throw new NotImplementedException(); } argValues[i] = m.Invoke(null, new object[] { exp }); } else { Visit(arg); argValues[i] = this.PopValue(); } } if (node.Method.IsStatic) { var value = node.Method.Invoke(null, argValues); PushValue(value); } else { Visit(node.Object); var instance = PopValue(); Debug.Assert(instance != null); var value = node.Method.Invoke(instance, argValues); PushValue(value); } return(node); }
public static IQueryProvider FindQueryProvider(Expression expr) { return(QueryProviderFinder.FindProvider(expr)); }