private static bool IsComparison(Expression expression) { MethodCallExpression mce = expression as MethodCallExpression; if (mce == null) { switch (expression.NodeType) { case ExpressionType.Equal: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.NotEqual: return(true); default: return(false); } } ExpressionType ignored; return(MethodCallConverter.GetVBObjectComparisonType(mce, out ignored)); }
protected override Expression VisitBinary(BinaryExpression b) { BinaryExpression binaryExpression = b.Left as BinaryExpression; ConstantExpression constant = b.Right as ConstantExpression; // Ignore VB coalesce operator. if (binaryExpression != null && b.NodeType == ExpressionType.Coalesce) { // VB translates comparisons against nullable values to the following expression: // (comparison) ?? false // E.g. (nullableInt > 5) ?? false // Because we don't support coalesce on the server, we will convert this expression to: // (comparison) // E.g. (nullableInt > 5) if (constant != null && constant.Type == typeof(bool) && ((bool)constant.Value == false) && MethodCallConverter.IsComparison(b.Left)) { return(Expression.MakeBinary(binaryExpression.NodeType, binaryExpression.Left, binaryExpression.Right)); } } MethodCallExpression mce = b.Left as MethodCallExpression; // Translate VB equality/inequality comparisons into normal string comparisons bool isVbCompareString = mce != null && TypeIsVBOperatorsType(mce.Method.DeclaringType) && mce.Method.Name == "CompareString" && mce.Arguments.Count == 3; if (isVbCompareString && constant != null && constant.Type == typeof(int) && (int)constant.Value == 0) { Expression left = mce.Arguments[0]; Expression right = mce.Arguments[1]; bool caseSensitive = true; ConstantExpression textCompareParam = mce.Arguments[2] as ConstantExpression; if (textCompareParam != null && textCompareParam.Type == typeof(bool) && (bool)textCompareParam.Value == true) { // the CompareString param is means ignore case, so we invert here caseSensitive = false; } if ((b.NodeType == ExpressionType.Equal || b.NodeType == ExpressionType.NotEqual) && caseSensitive) { // Case sensitive equality/inequality comparisons translate to simple equality/inequality operators // CompareString(expr1, expr2, false) == 0 translates to expr1 == expr2 // CompareString(expr1, expr2, false) != 0 translates to expr1 != expr2 return(Expression.MakeBinary(b.NodeType, left, right)); } else { // for all other comparisons, we make an equivalent translation to string.Compare return(Expression.MakeBinary(b.NodeType, MakeVBCompare(left, right, caseSensitive), Expression.Constant(0))); } } return(base.VisitBinary(b)); }
public static List <ServiceQueryPart> Serialize(IQueryable query) { List <ServiceQueryPart> queryParts; Expression expr = query.Expression; MethodCallConverter converter = new MethodCallConverter(); expr = converter.Visit(expr); Visitor visitor = new Visitor(); visitor.Visit(expr, out queryParts); return(queryParts); }
protected override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" && m.Arguments.Count == 3) { ExpressionType comparisonType; if (MethodCallConverter.GetVBObjectComparisonType(m, out comparisonType)) { // Translate CompareObject[operator](x, y) to x [operator] y. ReadOnlyCollection <Expression> args = this.Visit(m.Arguments); return(Expression.MakeBinary(comparisonType, args[0], args[1])); } } else if (m.Method.DeclaringType.FullName == "Microsoft.VisualBasic.Interaction" && m.Method.Name == "IIf" && m.Arguments.Count == 3) { // Translate VB's "iif(test, truePart, falsePart)" into "test ? truePart : falsePart". ReadOnlyCollection <Expression> args = this.Visit(m.Arguments); return(Expression.Condition(args[0], args[1], args[2])); } return(base.VisitMethodCall(m)); }
protected override Expression VisitUnary(UnaryExpression u) { if (u.NodeType == ExpressionType.Convert) { Expression operand = this.Visit(u.Operand); if (u.Type == typeof(object)) { // Remove the conversion. return(operand); } else if (u.Type == typeof(bool) && (operand.NodeType == ExpressionType.Conditional || MethodCallConverter.IsComparison(operand))) { // We don't want to try and convert the conditional/comparison to a boolean because // its type may no longer be an object/string (the supported types for Conversions.ToBoolean). return(operand); } } return(base.VisitUnary(u)); }