/// <summary> /// Process method calls and translate them into OData. /// </summary> /// <param name="expression"> /// The expression to visit. /// </param> /// <returns> /// The visited expression. /// </returns> private Expression VisitMethodCall(MethodCallExpression expression) { // Look for either an instance or static method string methodName = null; MemberInfoKey methodInfoKey = new MemberInfoKey(expression.Method); if (InstanceMethods.TryGetValue(methodInfoKey, out methodName)) { this.VisitODataMethodCall(expression, methodName, false); } else if (StaticMethods.TryGetValue(methodInfoKey, out methodName)) { this.VisitODataMethodCall(expression, methodName, true); } else if (expression.Method.GetRuntimeBaseDefinition().Equals(toStringMethod)) { // handle the ToString method here // toString will only occur on expression that rely on a parameter, // because otherwise the partial evaluator would have already evaluated it // we get the base definition to detect overrides of ToString, which are pretty common this.Visit(expression.Object); } else { this.VisitCustomMethodCall(expression); } return(expression); }
/// <summary> /// Process member references. /// </summary> /// <param name="expression"> /// The expression to visit. /// </param> /// <returns> /// The visited expression. /// </returns> private Expression VisitMemberAccess(MemberExpression expression) { // Lookup the Mobile Services name of the member and use that string memberName = GetTableMemberName(expression, this.contractResolver); if (memberName != null) { this.filterExpression.Push(new MemberAccessNode(null, memberName)); return(expression); } // Check if this member is actually a function that looks like a // property (like string.Length, etc.) string methodName = null; MemberInfoKey memberInfoKey = new MemberInfoKey(expression.Member); if (InstanceProperties.TryGetValue(memberInfoKey, out methodName)) { var fnCallNode = new FunctionCallNode(methodName, null); this.filterExpression.Push(fnCallNode); this.Visit(expression.Expression); this.SetChildren(fnCallNode); return(expression); } // Otherwise we can't process the member. throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, "The member '{0}' is not supported in the 'Where' Mobile Services query expression '{1}'.", expression != null && expression.Member != null ? expression.Member.Name : null, expression != null ? expression.ToString() : null)); }