Repository: dotnet/efcore
File: src/EFCore.Cosmos/Query/Internal/CosmosValueConverterCompensatingExpressionVisitor.cs (C#)

Code before:
        var ifTrue = (SqlExpression)Visit(sqlConditionalExpression.IfTrue);
        var ifFalse = (SqlExpression)Visit(sqlConditionalExpression.IfFalse);

        return sqlConditionalExpression.Update(test, ifTrue, ifFalse);
    }

    [return: NotNullIfNotNull(nameof(sqlExpression))]
    private SqlExpression? TryCompensateForBoolWithValueConverter(SqlExpression? sqlExpression)
        => sqlExpression switch
        {
            ScalarAccessExpression keyAccessExpression
                when keyAccessExpression.TypeMapping!.ClrType == typeof(bool) && keyAccessExpression.TypeMapping!.Converter != null
                => sqlExpressionFactory.Equal(sqlExpression, sqlExpressionFactory.Constant(true, sqlExpression.TypeMapping)),

            SqlUnaryExpression sqlUnaryExpression
                => sqlUnaryExpression.Update(TryCompensateForBoolWithValueConverter(sqlUnaryExpression.Operand)),

            SqlBinaryExpression
            {
                OperatorType: ExpressionType.AndAlso or ExpressionType.OrElse,
                Left: SqlExpression left,
                Right: SqlExpression right
            } sqlBinaryExpression
                => sqlBinaryExpression.Update(
                    TryCompensateForBoolWithValueConverter(left),
                    TryCompensateForBoolWithValueConverter(right)),

            { TypeMapping.ClrType: var clrType, TypeMapping.Converter: not null }
                when clrType == typeof(bool) || clrType == typeof(bool?)
                => sqlExpressionFactory.Equal(sqlExpression, sqlExpressionFactory.Constant(true, sqlExpression.TypeMapping)),

            _ => sqlExpression
        };
}


Review comment (refactor):
The new switch arm compensates any bool/bool? expression with a value converter; with this in place, the earlier ScalarAccessExpression-specific arm becomes redundant (and only checks bool, not bool?). Consider removing/merging the earlier arm to avoid duplicated logic and future divergence.

Code after:
        var ifTrue = (SqlExpression)Visit(sqlConditionalExpression.IfTrue);
        var ifFalse = (SqlExpression)Visit(sqlConditionalExpression.IfFalse);

        return sqlConditionalExpression.Update(test, ifTrue, ifFalse);
    }

    [return: NotNullIfNotNull(nameof(sqlExpression))]
    private SqlExpression? TryCompensateForBoolWithValueConverter(SqlExpression? sqlExpression)
        => sqlExpression switch
        {
            SqlUnaryExpression sqlUnaryExpression
                => sqlUnaryExpression.Update(TryCompensateForBoolWithValueConverter(sqlUnaryExpression.Operand)),

            SqlBinaryExpression
            {
                OperatorType: ExpressionType.AndAlso or ExpressionType.OrElse,
                Left: SqlExpression left,
                Right: SqlExpression right
            } sqlBinaryExpression
                => sqlBinaryExpression.Update(
                    TryCompensateForBoolWithValueConverter(left),
                    TryCompensateForBoolWithValueConverter(right)),

            { TypeMapping.ClrType: var clrType, TypeMapping.Converter: not null }
                when clrType == typeof(bool) || clrType == typeof(bool?)
                => sqlExpressionFactory.Equal(sqlExpression, sqlExpressionFactory.Constant(true, sqlExpression.TypeMapping)),

            _ => sqlExpression
        };
}