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

Code before:
            }

            source = translatedSource;
        }

        var translation = _sqlExpressionFactory.ApplyDefaultTypeMapping(
            _sqlExpressionFactory.Function("COUNT", [_sqlExpressionFactory.Constant(1)], typeof(int)));

        var projectionMapping = new Dictionary<ProjectionMember, Expression> { { new ProjectionMember(), translation } };

        selectExpression.ClearOrdering();
        selectExpression.ReplaceProjectionMapping(projectionMapping);
        return source.UpdateShaperExpression(
            Expression.Convert(
                new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), returnType.MakeNullable()),
                returnType));
    }

    private ShapedQueryExpression? TranslateSetOperation(
        ShapedQueryExpression source1,
        ShapedQueryExpression source2,
        string functionName,
        bool ignoreOrderings = false)
    {
        if (source1.TryConvertToArray(_typeMappingSource, out var array1, out var projection1, ignoreOrderings)
            && source2.TryConvertToArray(_typeMappingSource, out var array2, out var projection2, ignoreOrderings)
            && projection1.Type == projection2.Type)
        {
            var arrayType = typeof(IEnumerable<>).MakeGenericType(projection1.Type);

            // Set operation over arrays of scalars
            if (projection1 is SqlExpression sqlProjection1
                && projection2 is SqlExpression sqlProjection2
                && (sqlProjection1.TypeMapping ?? sqlProjection2.TypeMapping) is CosmosTypeMapping typeMapping)
            {
                var arrayTypeMapping = _typeMappingSource.FindMapping(arrayType, _queryCompilationContext.Model, typeMapping);
                var translation = _sqlExpressionFactory.Function(functionName, [array1, array2], arrayType, arrayTypeMapping);
                var alias = _aliasManager.GenerateSourceAlias(translation);
                var select = SelectExpression.CreateForCollection(
                    translation, alias, new ScalarReferenceExpression(alias, projection1.Type, typeMapping));
                return source1.UpdateQueryExpression(select);
            }

            // Set operation over arrays of structural types
            if (source1.ShaperExpression is StructuralTypeShaperExpression { StructuralType: var structuralType1 }
                && source2.ShaperExpression is StructuralTypeShaperExpression { StructuralType: var structuralType2 }
                && structuralType1 == structuralType2)
            {
                var translation = new ObjectFunctionExpression(functionName, [array1, array2], arrayType);
                var alias = _aliasManager.GenerateSourceAlias(translation);
                var select = SelectExpression.CreateForCollection(

Review comment (bug):
The comment says this code will "throw" an error, but the implementation only adds translation error details and returns null (the exception is thrown later by the query pipeline). Consider rewording to avoid misleading future readers (e.g. "fail translation with an appropriate error").
```suggestion
        // Detect if either source is a root entity query and fail translation with an appropriate error.
```

Code after:
            }

            source = translatedSource;
        }

        var translation = _sqlExpressionFactory.ApplyDefaultTypeMapping(
            _sqlExpressionFactory.Function("COUNT", [_sqlExpressionFactory.Constant(1)], typeof(int)));

        var projectionMapping = new Dictionary<ProjectionMember, Expression> { { new ProjectionMember(), translation } };

        selectExpression.ClearOrdering();
        selectExpression.ReplaceProjectionMapping(projectionMapping);
        return source.UpdateShaperExpression(
            Expression.Convert(
                new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), returnType.MakeNullable()),
                returnType));
    }

    private ShapedQueryExpression? TranslateSetOperation(
        ShapedQueryExpression source1,
        ShapedQueryExpression source2,
        string functionName,
        bool ignoreOrderings = false)
    {
        // Cosmos set operations (Concat, Union, Intersect) can only be performed over arrays, not over root entity queries.
        // Detect if either source is a root entity query and throw an appropriate error.
        if (IsRootEntityQuery(source1) || IsRootEntityQuery(source2))
        {
            AddTranslationErrorDetails(CosmosStrings.NonCorrelatedSubqueriesNotSupported);
            return null;
        }

        if (source1.TryConvertToArray(_typeMappingSource, out var array1, out var projection1, ignoreOrderings)
            && source2.TryConvertToArray(_typeMappingSource, out var array2, out var projection2, ignoreOrderings)
            && projection1.Type == projection2.Type)
        {
            var arrayType = typeof(IEnumerable<>).MakeGenericType(projection1.Type);

            // Set operation over arrays of scalars
            if (projection1 is SqlExpression sqlProjection1
                && projection2 is SqlExpression sqlProjection2
                && (sqlProjection1.TypeMapping ?? sqlProjection2.TypeMapping) is CosmosTypeMapping typeMapping)
            {
                var arrayTypeMapping = _typeMappingSource.FindMapping(arrayType, _queryCompilationContext.Model, typeMapping);
                var translation = _sqlExpressionFactory.Function(functionName, [array1, array2], arrayType, arrayTypeMapping);
                var alias = _aliasManager.GenerateSourceAlias(translation);
                var select = SelectExpression.CreateForCollection(
                    translation, alias, new ScalarReferenceExpression(alias, projection1.Type, typeMapping));
                return source1.UpdateQueryExpression(select);
            }