Repository: dotnet/efcore
File: src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs (C#)

Code before:

        Check.DebugAssert(
            structuralTypeVariable != null || count == 0,
            "If there are any properties then the entity parameter must be used");
        var indicesExpression = parameter == null || !parameter.Type.IsAssignableTo(typeof(IInternalEntry))
            ? (Expression)Expression.Property(null, typeof(ReadOnlySpan<int>), nameof(ReadOnlySpan<>.Empty))
            : Expression.Call(parameter, PropertyAccessorsFactory.GetOrdinalsMethod);

        for (var i = 0; i < count; i++)
        {
            var propertyBase = propertyBases[i];

            switch (propertyBase)
            {
                case null:
                    arguments[i] = Expression.Constant(null);
                    types[i] = typeof(object);
                    continue;

                case IProperty property:
                    arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, property), property);
                    continue;

                case var _ when propertyBase.IsShadowProperty():
                    // Shadow property materialization on complex types is not currently supported (see #35613).
                    if (!UseOldBehavior37337 && propertyBase.DeclaringType is IComplexType)
                    {
                        arguments[i] = propertyBase.ClrType.GetDefaultValueConstant();
                        types[i] = propertyBase.ClrType;
                        continue;
                    }

                    arguments[i] = CreateSnapshotValueExpression(CreateReadShadowValueExpression(parameter, propertyBase), propertyBase);
                    continue;

                case IComplexProperty { IsCollection: false, IsNullable: true }:
                    // For nullable non-collection complex properties, convert to object to store the null reference
                    arguments[i] = Expression.Convert(
                        CreateSnapshotValueExpression(CreateReadValueExpression(parameter, propertyBase), propertyBase),
                        typeof(object));
                    continue;
            }

            arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, propertyBase), propertyBase);
        }

        var constructorExpression = Expression.Convert(
            Expression.New(
                Snapshot.CreateSnapshotType(types).GetDeclaredConstructor(types)!,
                arguments),
            typeof(ISnapshot));

Review comment (bug):
@copilot Microsoft.EntityFrameworkCore.Query.AdHocComplexTypeQuerySqliteTest.Nullable_complex_type_with_discriminator_and_shadow_property is still failing 

Code after:
        Check.DebugAssert(
            structuralTypeVariable != null || count == 0,
            "If there are any properties then the entity parameter must be used");
        var indicesExpression = parameter == null || !parameter.Type.IsAssignableTo(typeof(IInternalEntry))
            ? (Expression)Expression.Property(null, typeof(ReadOnlySpan<int>), nameof(ReadOnlySpan<>.Empty))
            : Expression.Call(parameter, PropertyAccessorsFactory.GetOrdinalsMethod);

        for (var i = 0; i < count; i++)
        {
            var propertyBase = propertyBases[i];

            switch (propertyBase)
            {
                case null:
                    arguments[i] = Expression.Constant(null);
                    types[i] = typeof(object);
                    continue;

                case IProperty property:
                    // Shadow property materialization on complex types is not currently supported (see #35613).
                    if (!UseOldBehavior37337 && propertyBase.DeclaringType is IComplexType && property.IsShadowProperty())
                    {
                        arguments[i] = propertyBase.ClrType.GetDefaultValueConstant();
                        types[i] = propertyBase.ClrType;
                        continue;
                    }

                    arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, property), property);
                    continue;

                case var _ when propertyBase.IsShadowProperty():
                    arguments[i] = CreateSnapshotValueExpression(CreateReadShadowValueExpression(parameter, propertyBase), propertyBase);
                    continue;

                case IComplexProperty { IsCollection: false, IsNullable: true }:
                    // For nullable non-collection complex properties, convert to object to store the null reference
                    arguments[i] = Expression.Convert(
                        CreateSnapshotValueExpression(CreateReadValueExpression(parameter, propertyBase), propertyBase),
                        typeof(object));
                    continue;
            }

            arguments[i] = CreateSnapshotValueExpression(CreateReadValueExpression(parameter, propertyBase), propertyBase);
        }

        var constructorExpression = Expression.Convert(
            Expression.New(
                Snapshot.CreateSnapshotType(types).GetDeclaredConstructor(types)!,
                arguments),
            typeof(ISnapshot));