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

Code before:

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    protected override Expression VisitUnary(UnaryExpression unaryExpression)
    {
        var operand = Visit(unaryExpression.Operand);

        if (operand is EntityReferenceExpression entityReferenceExpression
            && unaryExpression.NodeType is ExpressionType.Convert or ExpressionType.ConvertChecked or ExpressionType.TypeAs)
        {
            return entityReferenceExpression.Convert(unaryExpression.Type);
        }

        if (TranslationFailed(unaryExpression.Operand, operand, out var sqlOperand))
        {
            return QueryCompilationContext.NotTranslatedExpression;
        }

        return unaryExpression.NodeType switch
        {
            ExpressionType.Not
                => operand is SqlConstantExpression { Value: false } ? sqlExpressionFactory.Constant(true) :  sqlExpressionFactory.Not(sqlOperand!),

            ExpressionType.Negate or ExpressionType.NegateChecked
                => sqlExpressionFactory.Negate(sqlOperand!),

            // Convert nodes can be an explicit user gesture in the query, or they may get introduced by the compiler (e.g. when a Child is
            // passed as an argument for a parameter of type Parent). The latter type should generally get stripped out as a pure C#/LINQ
            // artifact that shouldn't affect translation, but the latter may be an indication from the user that they want to apply a
            // type change.
            ExpressionType.Convert or ExpressionType.ConvertChecked or ExpressionType.TypeAs
                when operand.Type.IsInterface && unaryExpression.Type.GetInterfaces().Any(e => e == operand.Type)
                // We strip out implicit conversions, e.g. float[] -> ReadOnlyMemory<float> (for vector search)
                || (unaryExpression.Method is { IsSpecialName: true, Name: "op_Implicit" }
                    && IsReadOnlyMemory(unaryExpression.Type.UnwrapNullableType()))
                || unaryExpression.Type.UnwrapNullableType() == operand.Type
                || unaryExpression.Type.UnwrapNullableType() == typeof(Enum)
                // Object convert needs to be converted to explicit cast when mismatching types
                // But we let it pass here since we don't have explicit cast mechanism here and in some cases object convert is due to value types
                || unaryExpression.Type == typeof(object)
                => sqlOperand!,

            _ => QueryCompilationContext.NotTranslatedExpression
        };

        static bool IsReadOnlyMemory(Type type)
            => type is { IsGenericType: true, IsGenericTypeDefinition: false }

Review comment (suggestion):
We can also handle the case where it's a constant `true` (returning `false`).

I'd change the switch statement to be over unaryExprsesion rather than unaryExpression.NodeType, and then use pattern matching for the cases.

Code after:

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    protected override Expression VisitUnary(UnaryExpression unaryExpression)
    {
        var operand = Visit(unaryExpression.Operand);

        if (operand is EntityReferenceExpression entityReferenceExpression
            && unaryExpression.NodeType is ExpressionType.Convert or ExpressionType.ConvertChecked or ExpressionType.TypeAs)
        {
            return entityReferenceExpression.Convert(unaryExpression.Type);
        }

        if (TranslationFailed(unaryExpression.Operand, operand, out var sqlOperand))
        {
            return QueryCompilationContext.NotTranslatedExpression;
        }

        return unaryExpression.NodeType switch
        {
            ExpressionType.Not when operand is SqlConstantExpression { Value: bool boolValue }
                => sqlExpressionFactory.Constant(!boolValue),
            ExpressionType.Not
                => sqlExpressionFactory.Not(sqlOperand!),

            ExpressionType.Negate or ExpressionType.NegateChecked
                => sqlExpressionFactory.Negate(sqlOperand!),

            // Convert nodes can be an explicit user gesture in the query, or they may get introduced by the compiler (e.g. when a Child is
            // passed as an argument for a parameter of type Parent). The latter type should generally get stripped out as a pure C#/LINQ
            // artifact that shouldn't affect translation, but the latter may be an indication from the user that they want to apply a
            // type change.
            ExpressionType.Convert or ExpressionType.ConvertChecked or ExpressionType.TypeAs
                when operand.Type.IsInterface && unaryExpression.Type.GetInterfaces().Any(e => e == operand.Type)
                // We strip out implicit conversions, e.g. float[] -> ReadOnlyMemory<float> (for vector search)
                || (unaryExpression.Method is { IsSpecialName: true, Name: "op_Implicit" }
                    && IsReadOnlyMemory(unaryExpression.Type.UnwrapNullableType()))
                || unaryExpression.Type.UnwrapNullableType() == operand.Type
                || unaryExpression.Type.UnwrapNullableType() == typeof(Enum)
                // Object convert needs to be converted to explicit cast when mismatching types
                // But we let it pass here since we don't have explicit cast mechanism here and in some cases object convert is due to value types
                || unaryExpression.Type == typeof(object)
                => sqlOperand!,

            _ => QueryCompilationContext.NotTranslatedExpression
        };