예제 #1
0
        /// <inheritdoc />
        protected override Expression VisitUnary(UnaryExpression unaryExpression)
        {
            if (unaryExpression.NodeType == ExpressionType.ArrayLength)
            {
                if (TranslationFailed(unaryExpression.Operand, Visit(unaryExpression.Operand), out var sqlOperand))
                {
                    return(QueryCompilationContext.NotTranslatedExpression);
                }

                // Translate Length on byte[], but only if the type mapping is for bytea. There's also array of bytes
                // (mapped to smallint[]), which is handled below with CARDINALITY.
                if (sqlOperand.Type == typeof(byte[]) &&
                    (sqlOperand.TypeMapping == null || sqlOperand.TypeMapping is NpgsqlByteArrayTypeMapping))
                {
                    return(_sqlExpressionFactory.Function(
                               "length",
                               new[] { sqlOperand },
                               nullable: true,
                               argumentsPropagateNullability: TrueArrays[1],
                               typeof(int)));
                }

                return(_jsonPocoTranslator.TranslateArrayLength(sqlOperand) ??
                       _sqlExpressionFactory.Function(
                           "cardinality",
                           new[] { sqlOperand },
                           nullable: true,
                           argumentsPropagateNullability: TrueArrays[1],
                           typeof(int)));
            }

            return(base.VisitUnary(unaryExpression));
        }
예제 #2
0
        /// <inheritdoc />
        protected override Expression VisitUnary(UnaryExpression unaryExpression)
        {
            if (unaryExpression.NodeType == ExpressionType.ArrayLength)
            {
                if (TranslationFailed(unaryExpression.Operand, Visit(unaryExpression.Operand), out var sqlOperand))
                {
                    return(null);
                }

                return(_jsonPocoTranslator.TranslateArrayLength(sqlOperand) ??
                       _sqlExpressionFactory.Function("cardinality", new[] { sqlOperand }, typeof(int?)));
            }

            return(base.VisitUnary(unaryExpression));
        }
예제 #3
0
    /// <inheritdoc />
    protected override Expression VisitUnary(UnaryExpression unaryExpression)
    {
        switch (unaryExpression.NodeType)
        {
        case ExpressionType.ArrayLength:
            if (TranslationFailed(unaryExpression.Operand, Visit(unaryExpression.Operand), out var sqlOperand))
            {
                return(QueryCompilationContext.NotTranslatedExpression);
            }

            // Translate Length on byte[], but only if the type mapping is for bytea. There's also array of bytes
            // (mapped to smallint[]), which is handled below with CARDINALITY.
            if (sqlOperand !.Type == typeof(byte[]) &&
                (sqlOperand.TypeMapping is null || sqlOperand.TypeMapping is NpgsqlByteArrayTypeMapping))
            {
                return(_sqlExpressionFactory.Function(
                           "length",
                           new[] { sqlOperand },
                           nullable: true,
                           argumentsPropagateNullability: TrueArrays[1],
                           typeof(int)));
            }

            return(_jsonPocoTranslator.TranslateArrayLength(sqlOperand)
                   ?? _sqlExpressionFactory.Function(
                       "cardinality",
                       new[] { sqlOperand },
                       nullable: true,
                       argumentsPropagateNullability: TrueArrays[1],
                       typeof(int)));

        // We have row value comparison methods such as EF.Functions.GreaterThan, which accept two ValueTuples/Tuples.
        // Since they accept ITuple parameters, the arguments have a Convert node casting up from the concrete argument to ITuple;
        // this node causes translation failure in RelationalSqlTranslatingExpressionVisitor, so unwrap here.
        case ExpressionType.Convert
            when unaryExpression.Type == typeof(ITuple) && unaryExpression.Operand.Type.IsAssignableTo(typeof(ITuple)):
            return(Visit(unaryExpression.Operand));
        }

        return(base.VisitUnary(unaryExpression));
    }