/// <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)); }
/// <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)); }
/// <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)); }