diff --git a/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs b/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs index a3e9a6f84..5e52e6e91 100644 --- a/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs +++ b/Orm/Xtensive.Orm/Orm/Building/Builders/PartialIndexFilterBuilder.cs @@ -49,7 +49,8 @@ public static void BuildFilter(IndexInfo index) protected override Expression VisitBinary(BinaryExpression b) { - if (EnumRewritableOperations(b)) { + var nodeType = b.NodeType; + if (EnumRewritableOperations(nodeType)) { var leftNoCasts = b.Left.StripCasts(); var leftNoCastsType = leftNoCasts.Type; var bareLeftType = leftNoCastsType.StripNullable(); @@ -63,7 +64,7 @@ protected override Expression VisitBinary(BinaryExpression b) : leftNoCastsType.GetEnumUnderlyingType(); return base.VisitBinary(Expression.MakeBinary( - b.NodeType, + nodeType, Expression.Convert(leftNoCasts, typeToCast), Expression.Convert(b.Right, typeToCast))); } @@ -73,7 +74,7 @@ protected override Expression VisitBinary(BinaryExpression b) : rightNoCastsType.GetEnumUnderlyingType(); return base.VisitBinary(Expression.MakeBinary( - b.NodeType, + nodeType, Expression.Convert(rightNoCasts, typeToCast), Expression.Convert(b.Left, typeToCast))); } @@ -81,23 +82,22 @@ protected override Expression VisitBinary(BinaryExpression b) // Detect f!=null and f==null for entity fields - if (!(b.NodeType is ExpressionType.Equal or ExpressionType.NotEqual)) - return base.VisitBinary(b); - - var left = Visit(b.Left); - var right = Visit(b.Right); - - if (entityAccessMap.TryGetValue(left, out var field) && IsNull(right)) - return BuildEntityCheck(field, b.NodeType); - if (entityAccessMap.TryGetValue(right, out field) && IsNull(left)) - return BuildEntityCheck(field, b.NodeType); - if (entityAccessMap.TryGetValue(left, out var _) && entityAccessMap.TryGetValue(right, out var _)) - throw UnableToTranslate(b, Strings.ComparisonOfTwoEntityFieldsIsNotSupported); + if (nodeType is ExpressionType.Equal or ExpressionType.NotEqual) { + var left = Visit(b.Left); + var right = Visit(b.Right); + bool hasLeftField, hasRightField; + if ((hasLeftField = entityAccessMap.TryGetValue(left, out var field)) && IsNull(right) + || (hasRightField = entityAccessMap.TryGetValue(right, out field)) && IsNull(left)) { + return BuildEntityCheck(field, nodeType); + } + if (hasLeftField && hasRightField) + throw UnableToTranslate(b, Strings.ComparisonOfTwoEntityFieldsIsNotSupported); + } return base.VisitBinary(b); - static bool EnumRewritableOperations(BinaryExpression b) => - b.NodeType is ExpressionType.Equal or ExpressionType.NotEqual or ExpressionType.GreaterThan or ExpressionType.GreaterThanOrEqual + static bool EnumRewritableOperations(ExpressionType nodeType) => + nodeType is ExpressionType.Equal or ExpressionType.NotEqual or ExpressionType.GreaterThan or ExpressionType.GreaterThanOrEqual or ExpressionType.LessThan or ExpressionType.LessThanOrEqual; }