Beispiel #1
0
        /// <inheritdoc />
        protected override Expression VisitBinary(BinaryExpression binaryExpression)
        {
            // Support DateTime subtraction, which returns a TimeSpan.
            if (binaryExpression.NodeType == ExpressionType.Subtract &&
                binaryExpression.Left.Type.UnwrapNullableType() == typeof(DateTime) &&
                binaryExpression.Left.Type.UnwrapNullableType() == typeof(DateTime))
            {
                if (TranslationFailed(binaryExpression.Left, Visit(TryRemoveImplicitConvert(binaryExpression.Left)), out var sqlLeft) ||
                    TranslationFailed(binaryExpression.Right, Visit(TryRemoveImplicitConvert(binaryExpression.Right)), out var sqlRight))
                {
                    return(null);
                }

                var inferredDateTimeTypeMapping = ExpressionExtensions.InferTypeMapping(sqlLeft, sqlRight);
                return(new SqlBinaryExpression(
                           ExpressionType.Subtract,
                           _sqlExpressionFactory.ApplyTypeMapping(sqlLeft, inferredDateTimeTypeMapping),
                           _sqlExpressionFactory.ApplyTypeMapping(sqlRight, inferredDateTimeTypeMapping),
                           typeof(TimeSpan),
                           null));
            }

            if (binaryExpression.NodeType == ExpressionType.ArrayIndex)
            {
                if (TranslationFailed(binaryExpression.Left, Visit(TryRemoveImplicitConvert(binaryExpression.Left)), out var sqlLeft) ||
                    TranslationFailed(binaryExpression.Right, Visit(TryRemoveImplicitConvert(binaryExpression.Right)), out var sqlRight))
                {
                    return(null);
                }

                // ArrayIndex over bytea is special, we have to use function rather than subscript
                if (binaryExpression.Left.Type == typeof(byte[]))
                {
                    return(_sqlExpressionFactory.Function(
                               "get_byte",
                               new[]
                    {
                        _sqlExpressionFactory.ApplyDefaultTypeMapping(sqlLeft),
                        _sqlExpressionFactory.ApplyDefaultTypeMapping(sqlRight)
                    },
                               nullable: true,
                               argumentsPropagateNullability: TrueArrays[2],
                               typeof(byte),
                               _typeMappingSource.FindMapping(typeof(byte))
                               ));
                }

                return
                    // Try translating ArrayIndex inside json column
                    (_jsonPocoTranslator.TranslateMemberAccess(sqlLeft, sqlRight, binaryExpression.Type) ??
                     // Other types should be subscriptable - but PostgreSQL arrays are 1-based, so adjust the index.
                     _sqlExpressionFactory.ArrayIndex(sqlLeft, GenerateOneBasedIndexExpression(sqlRight)));
            }

            return(base.VisitBinary(binaryExpression));
        }