protected override Expression VisitMethodCall(MethodCallExpression methodCall) { if (QueryableTransformer.IsQueryableExtension(methodCall.Method)) { return(this.ReplaceQueryableMethod(methodCall)); } return(base.VisitMethodCall(methodCall)); }
private static MethodInfo ReplaceQueryableMethod(MethodInfo method) { MethodInfo matchingMethod = QueryableTransformer.GetMatchingMethod(method, QueryableTransformer.GetTargetDeclaringType(method)); if (matchingMethod != null) { return(matchingMethod); } throw new InvalidOperationException(string.Format("There is no method {0} on type {1} that matches the specified arguments", method.Name, method.DeclaringType.FullName)); }
private static bool MethodMatch(MethodInfo candidate, MethodInfo method) { if (candidate.Name != method.Name) { return(false); } if (!QueryableTransformer.HasExtensionAttribute(candidate)) { return(false); } Type[] parameterTypes = method.GetParameterTypes(); if (parameterTypes.Length != candidate.GetParameters().Length) { return(false); } if (method.IsGenericMethod) { if (!candidate.IsGenericMethod) { return(false); } if (candidate.GetGenericArguments().Length != method.GetGenericArguments().Length) { return(false); } candidate = candidate.MakeGenericMethodFrom(method); } if (!QueryableTransformer.TypeMatch(candidate.ReturnType, method.ReturnType)) { return(false); } Type[] parameterTypes2 = candidate.GetParameterTypes(); if (parameterTypes2[0] != QueryableTransformer.GetComparableType(parameterTypes[0])) { return(false); } for (int i = 1; i < parameterTypes2.Length; i++) { if (!QueryableTransformer.TypeMatch(parameterTypes2[i], parameterTypes[i])) { return(false); } } return(true); }
private MethodCallExpression ReplaceQueryableMethod(MethodCallExpression old) { Expression obj = null; if (old.Object != null) { obj = this.Visit(old.Object); } MethodInfo methodInfo = QueryableTransformer.ReplaceQueryableMethod(old.Method); ParameterInfo[] parameters = methodInfo.GetParameters(); Expression[] array = new Expression[old.Arguments.Count]; for (int i = 0; i < array.Length; i++) { array[i] = QueryableTransformer.UnquoteIfNeeded(this.Visit(old.Arguments[i]), parameters[i].ParameterType); } return(new MethodCallExpression(obj, methodInfo, array.ToReadOnlyCollection <Expression>())); }
private static MethodInfo GetMatchingMethod(MethodInfo method, Type declaring) { MethodInfo[] methods = declaring.GetMethods(); int i = 0; while (i < methods.Length) { MethodInfo methodInfo = methods[i]; if (!QueryableTransformer.MethodMatch(methodInfo, method)) { i++; } else { if (method.IsGenericMethod) { return(methodInfo.MakeGenericMethodFrom(method)); } return(methodInfo); } } return(null); }
private static bool IsQueryableExtension(MethodInfo method) { return(QueryableTransformer.HasExtensionAttribute(method) && method.GetParameters()[0].ParameterType.IsAssignableTo(typeof(IQueryable))); }
private static bool TypeMatch(Type candidate, Type type) { return(candidate == type || candidate == QueryableTransformer.GetComparableType(type)); }