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

Code before:
                {
                    continue;
                }
                
                flags[i] = GetValueInternal(InternalEntry, complexProperty) == null;
            }
        }

        var cloned = new ArrayPropertyValues(InternalEntry, values, flags);

        foreach (var complexProperty in ComplexCollectionProperties)
        {
            var collection = (IList?)GetValueInternal(InternalEntry, complexProperty);
            if (collection != null)
            {
                cloned[complexProperty] = collection;
            }
        }

        return cloned;
    }
    
    private bool IsContainingComplexPropertyNull(IComplexProperty complexProperty)
    {
        var declaringType = complexProperty.DeclaringType;
        while (declaringType is IComplexType complexType)
        {
            var containingProperty = complexType.ComplexProperty;
            if (GetValueInternal(InternalEntry, containingProperty) == null)
            {
                return true;
            }
            declaringType = containingProperty.DeclaringType;
        }
        return false;
    }

    /// <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>
    public override void SetValues(PropertyValues propertyValues)
    {
        Check.NotNull(propertyValues);

        var nullableComplexProperties = NullableComplexProperties;
        HashSet<IComplexProperty>? nullComplexProperties = null;
        if (nullableComplexProperties != null)
        {

Review comment (suggestion):
@copilot Just check the first parent, no need to loop. If the complex property corresponding to the declaringType is a collection, return false

Code after:

        foreach (var complexProperty in ComplexCollectionProperties)
        {
            var collection = (IList?)GetValueInternal(InternalEntry, complexProperty);
            if (collection != null)
            {
                cloned[complexProperty] = collection;
            }
        }

        return cloned;
    }

    /// <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>
    public override void SetValues(PropertyValues propertyValues)
    {
        Check.NotNull(propertyValues);

        var nullableComplexProperties = NullableComplexProperties;
        HashSet<IComplexProperty>? nullComplexProperties = null;
        if (nullableComplexProperties != null)
        {
            for (var i = 0; i < nullableComplexProperties.Count; i++)
            {
                if (propertyValues.IsNullableComplexPropertyNull(i))
                {
                    nullComplexProperties ??= [];
                    nullComplexProperties.Add(nullableComplexProperties[i]);
                }
            }
        }

        foreach (var property in Properties)
        {
            if (nullComplexProperties != null && IsPropertyInNullComplexType(property, nullComplexProperties))
            {
                continue;
            }

            SetValueInternal(InternalEntry, property, propertyValues[property]);
        }

        foreach (var complexProperty in ComplexCollectionProperties)
        {
            SetValueInternal(InternalEntry, complexProperty, propertyValues[complexProperty]);
        }