protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.HasArgImplementing(typeof(IQueryable))) { var newArgs = node.Arguments.Select(a => StripQuotes(base.Visit(a))).ToArray(); // TODO: This is an imperfect shortcut to find an Enumerable // method that corresponds to the given Queryable method. // Should work for most (if not all) LINQ operators, though, // which is primarily what we are after. To do this // "correctly", i.e., the same as what the compiler does, // we'd need to effectively reproduce extension method lookup, // generic overload resolution, etc. This is not trivial. var newMethod = typeof(Enumerable).GetMethods().FirstOrDefault( m => m.Name == node.Method.Name && newArgs.Length == m.GetParameters().Length && newArgs.Zip(m.GetParameters().Select(p => p.ParameterType), (arg, type) => arg.Type.Implements(type.GetGenericTypeDefinition())).All(b => b == true)); if (newMethod == null) { throw new Exception("Couldn't find IEnumerable<> replacement for method " + node.Method.Name); } if (newMethod.IsGenericMethod) { newMethod = newMethod.MakeGenericMethod(node.Method.GetGenericArguments().Select( t => t.Implements(typeof(IQueryable <>)) ? typeof(IEnumerable <>).MakeGenericType(t.GetGenericArguments()[0]) : t).ToArray()); } return(Expression.Call(newMethod, newArgs)); } else { return(base.VisitMethodCall(node)); } }