//https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752358 private BinaryExpression CreateBinaryExpression(string equalityOperator, MemberExpression memberExpression, ConstantExpression constantExpression) { switch (equalityOperator) { case "eq": return(BinaryExpression.Equal(memberExpression, constantExpression)); case "ne": return(BinaryExpression.NotEqual(memberExpression, constantExpression)); case "gt": return(BinaryExpression.GreaterThan(memberExpression, constantExpression)); case "lt": return(BinaryExpression.LessThan(memberExpression, constantExpression)); case "ge": return(BinaryExpression.GreaterThanOrEqual(memberExpression, constantExpression)); case "le": return(BinaryExpression.LessThanOrEqual(memberExpression, constantExpression)); default: throw new System.Exception("Unnown equality operator"); } }
/// <summary> /// Visit Visual Basic Compare expression /// </summary> /// <param name="expression">Method call expression Compare expression</param> /// <param name="binExpNodeType">Binary expression node type</param> /// <returns> /// Reduced expression. /// </returns> protected virtual Expression VisitCompare(MethodCallExpression expression, ExpressionType binExpNodeType) { var left = expression.Arguments[0]; var right = expression.Arguments[1]; switch (binExpNodeType) { case ExpressionType.Equal: return(BinaryExpression.Equal(left, right)); case ExpressionType.NotEqual: return(BinaryExpression.NotEqual(left, right)); case ExpressionType.LessThan: return(BinaryExpression.LessThan(left, right)); case ExpressionType.LessThanOrEqual: return(BinaryExpression.LessThanOrEqual(left, right)); case ExpressionType.GreaterThan: return(BinaryExpression.GreaterThan(left, right)); case ExpressionType.GreaterThanOrEqual: return(BinaryExpression.GreaterThanOrEqual(left, right)); } return(ThrowNotSupportedException(expression)); }
BinaryExpression FlipExpression(BinaryExpression binex) { if (binex.NodeType == ExpressionType.GreaterThan) { return(BinaryExpression.LessThan(binex.Right, binex.Left)); } if (binex.NodeType == ExpressionType.GreaterThanOrEqual) { return(BinaryExpression.LessThanOrEqual(binex.Right, binex.Left)); } if (binex.NodeType == ExpressionType.LessThan) { return(BinaryExpression.GreaterThan(binex.Right, binex.Left)); } if (binex.NodeType == ExpressionType.LessThanOrEqual) { return(BinaryExpression.GreaterThanOrEqual(binex.Right, binex.Left)); } return(Expression.MakeBinary(binex.NodeType, binex.Right, binex.Left)); }
/// <summary> /// Checks if the binary expression is a string comparison emitted by the Visual Basic compiler. /// </summary> /// <remarks>The VB compiler translates string comparisons such as /// <code>(Function(x) x.Name = "a string value")</code> not as a binary expression with the field /// on the left side and the string value on the right side. Instead, it converts it into a call /// to <code>Microsoft.VisualBasic.CompilerServices.Operators.CompareString</code> (or /// <code>Microsoft.VisualBasic.CompilerServices.EmbeddedOperators</code> for phone platforms) /// for the string value, and compares the expression to zero.</remarks> /// <param name="expression">The binary expression to check.</param> /// <param name="stringComparison">A normalized string comparison expression.</param> /// <returns>True if the expression is a string comparison expression emitted by the VB compiler, /// otherwise false</returns> private bool CheckVBStringCompareExpression(BinaryExpression expression, out BinaryExpression stringComparison) { stringComparison = null; if (expression.Left.Type == typeofInt && expression.Left.NodeType == ExpressionType.Call && expression.Right.Type == typeofInt && expression.Right.NodeType == ExpressionType.Constant && ((ConstantExpression)expression.Right).Value.Equals(0)) { MethodCallExpression methodCall = (MethodCallExpression)expression.Left; if ((methodCall.Method.DeclaringType.FullName == VBOperatorClass || methodCall.Method.DeclaringType.FullName == VBOperatorClassAlt) && methodCall.Method.Name == VBCompareStringMethod && methodCall.Arguments.Count == VBCompareStringArguments && methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex].Type == typeof(bool) && methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex].NodeType == ExpressionType.Constant) { bool doCaseInsensitiveComparison = ((ConstantExpression)methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex]).Value.Equals(true); Expression leftExpression = methodCall.Arguments[0]; Expression rightExpression = methodCall.Arguments[1]; if (doCaseInsensitiveComparison) { leftExpression = MethodCallExpression.Call(leftExpression, stringToLowerMethod); rightExpression = MethodCallExpression.Call(rightExpression, stringToLowerMethod); } switch (expression.NodeType) { case ExpressionType.Equal: stringComparison = BinaryExpression.Equal(leftExpression, rightExpression); break; case ExpressionType.NotEqual: stringComparison = BinaryExpression.NotEqual(leftExpression, rightExpression); break; case ExpressionType.LessThan: stringComparison = BinaryExpression.LessThan(leftExpression, rightExpression); break; case ExpressionType.LessThanOrEqual: stringComparison = BinaryExpression.LessThanOrEqual(leftExpression, rightExpression); break; case ExpressionType.GreaterThan: stringComparison = BinaryExpression.GreaterThan(leftExpression, rightExpression); break; case ExpressionType.GreaterThanOrEqual: stringComparison = BinaryExpression.GreaterThanOrEqual(leftExpression, rightExpression); break; } if (stringComparison != null) { return(true); } } } return(false); }
public object CreateBusinessQueryExpression(IList <SearchingArgument> SearchingArguments) { Expression <Func <Business, bool> > expression = b => (true); if (SearchingArguments != null && SearchingArguments.Count > 0) { ParameterExpression parameter = Expression.Parameter(typeof(Business), "b"); MemberExpression member; ConstantExpression value = Expression.Constant(1); Expression body = BinaryExpression.Equal(value, value); Expression predicate = body; foreach (var arg in SearchingArguments) { member = Expression.Property(parameter, arg.FieldName); value = Expression.Constant(arg.FieldValue); switch (arg.Operator) { case OperatorEnum.EqualTo: body = BinaryExpression.Equal(member, value); break; case OperatorEnum.NotEqualTo: body = BinaryExpression.NotEqual(member, value); break; case OperatorEnum.GreaterThan: body = BinaryExpression.GreaterThan(member, value); break; case OperatorEnum.GreaterThanOrEqualTo: body = BinaryExpression.GreaterThanOrEqual(member, value); break; case OperatorEnum.In: body = Expression.Call(value, value.Type.GetInterface("ICollection`1").GetMethod("Contains"), member); break; case OperatorEnum.NotIn: body = BinaryExpression.Not(Expression.Call(value, value.Type.GetInterface("ICollection`1").GetMethod("Contains"), member)); break; case OperatorEnum.Is: break; case OperatorEnum.IsNot: break; case OperatorEnum.LessThan: body = BinaryExpression.LessThan(member, value); break; case OperatorEnum.LessThanOrEqualTo: body = BinaryExpression.LessThanOrEqual(member, value); break; case OperatorEnum.StartsWith: body = Expression.Call(member, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), value); break; case OperatorEnum.NotStartWith: body = BinaryExpression.Not(Expression.Call(member, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), value)); break; case OperatorEnum.EndsWith: body = Expression.Call(member, typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), value); break; case OperatorEnum.NotEndWith: body = BinaryExpression.Not(Expression.Call(member, typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), value)); break; case OperatorEnum.Includes: body = Expression.Call(member, member.Type.GetMethod("Contains"), value); break; case OperatorEnum.NotInclude: body = BinaryExpression.Not(Expression.Call(member, member.Type.GetMethod("Contains"), value)); break; default: break; } predicate = arg.LogicalOperator == LogicalOperatorEnum.And ? BinaryExpression.And(predicate, body) : BinaryExpression.Or(predicate, body); } expression = Expression.Lambda <Func <Business, bool> >(predicate, parameter); } return(expression); }