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

Code before:
            if (property.GetOriginalValueIndex() >= 0
                && !entry.IsModified(property)
                && !entry.IsConceptualNull(property))
            {
                if (DetectValueChange(entry, property))
                {
                    changesFound = true;
                }
            }

            if (DetectKeyChange(entry, property))
            {
                changesFound = true;
            }
        }

        foreach (var complexProperty in entry.StructuralType.GetFlattenedComplexProperties())
        {
            if (complexProperty.IsCollection)
            {
                if (DetectComplexCollectionChanges(entry, complexProperty))
                {
                    changesFound = true;
                }
            }
            else if (ShouldDetectComplexPropertyChange(entry, complexProperty, setModified: true, out _))
            {
                if (DetectComplexPropertyChange(entry, complexProperty))
                {
                    changesFound = true;
                }
            }
        }

        return changesFound;
    }

    /// <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 virtual bool DetectComplexPropertyChange(InternalEntryBase entry, IComplexProperty complexProperty)
    {
        Check.DebugAssert(!complexProperty.IsCollection, $"Expected {complexProperty.Name} to not be a collection.");

        var currentValue = entry[complexProperty];
        var originalValue = entry.GetOriginalValue(complexProperty);

        if ((currentValue is null) != (originalValue is null))

Review comment (refactor):
@copilot The condition here is simpler than above, son inline both ShouldDetectComplexPropertyChange calls and simplify this check

Code after:
                    changesFound = true;
                }
            }
            else if (!UseOldBehavior37387
                && complexProperty.IsNullable
                && complexProperty.GetOriginalValueIndex() >= 0)
            {
                if (DetectComplexPropertyChange(entry, complexProperty))
                {
                    changesFound = true;
                }
            }
        }

        return changesFound;
    }

    /// <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 virtual bool DetectComplexPropertyChange(InternalEntryBase entry, IComplexProperty complexProperty)
    {
        Check.DebugAssert(!complexProperty.IsCollection, $"Expected {complexProperty.Name} to not be a collection.");

        var currentValue = entry[complexProperty];
        var originalValue = entry.GetOriginalValue(complexProperty);

        if ((currentValue is null) != (originalValue is null))
        {
            // If it changed from null to non-null, mark all inner properties as modified
            // to ensure the entity is detected as modified and the complex type properties are persisted
            if (currentValue is not null)
            {
                foreach (var innerProperty in complexProperty.ComplexType.GetFlattenedProperties())
                {
                    // Only mark properties that are tracked and can be modified
                    if (innerProperty.GetOriginalValueIndex() >= 0
                        && innerProperty.GetAfterSaveBehavior() == PropertySaveBehavior.Save)
                    {
                        entry.SetPropertyModified(innerProperty);
                    }
                }
            }

            return true;
        }

        return false;