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

Code before:
    public virtual void PropertyChanged(IInternalEntry entry, IPropertyBase propertyBase, bool setModified)
    {
        if (entry.EntityState is EntityState.Detached
            || propertyBase is IServiceProperty)
        {
            return;
        }

        switch (propertyBase)
        {
            case IProperty property:
                if (entry.EntityState is not EntityState.Deleted)
                {
                    entry.SetPropertyModified(property, setModified);
                }
                else
                {
                    ThrowIfKeyChanged(entry, property);
                }

                DetectKeyChange(entry, property);
                break;

            case IComplexProperty { IsCollection: false } complexProperty:
                // TODO: Automatic detection of complex property changes requires notification change tracking.
                // Currently only works with snapshot change tracking through DetectChanges.
                // Issue #36175
                if (!UseOldBehavior37387
                    && entry.EntityState is not EntityState.Deleted
                    && setModified
                    && complexProperty.IsNullable
                    && complexProperty.GetOriginalValueIndex() >= 0
                    && entry is InternalEntryBase entryBase)
                {
                    DetectComplexPropertyChange(entryBase, complexProperty);
                }
                break;

            case INavigationBase navigation when propertyBase.GetRelationshipIndex() != -1:
                DetectNavigationChange(
                    entry as InternalEntityEntry ?? throw new UnreachableException("Complex type entry with a navigation"), navigation);
                break;
        }
    }

    private static void ThrowIfKeyChanged(IInternalEntry entry, IProperty property)
    {
        if (property.IsKey()
            && property.GetAfterSaveBehavior() == PropertySaveBehavior.Throw)
        {
            throw new InvalidOperationException(CoreStrings.KeyReadOnly(property.Name, entry.StructuralType.DisplayName()));

Review comment (suggestion):
@copilot 
```suggestion
            case IComplexProperty { IsCollection: false } complexProperty:
                // TODO: This requires notification change tracking for complex types
                // Issue #36175
```

Code after:
    public virtual void PropertyChanged(IInternalEntry entry, IPropertyBase propertyBase, bool setModified)
    {
        if (entry.EntityState is EntityState.Detached
            || propertyBase is IServiceProperty)
        {
            return;
        }

        switch (propertyBase)
        {
            case IProperty property:
                if (entry.EntityState is not EntityState.Deleted)
                {
                    entry.SetPropertyModified(property, setModified);
                }
                else
                {
                    ThrowIfKeyChanged(entry, property);
                }

                DetectKeyChange(entry, property);
                break;

            case IComplexProperty { IsCollection: false } complexProperty:
                // TODO: This requires notification change tracking for complex types
                // Issue #36175
                if (!UseOldBehavior37387
                    && entry.EntityState is not EntityState.Deleted
                    && setModified
                    && entry is InternalEntryBase entryBase
                    && complexProperty.IsNullable 
                    && complexProperty.GetOriginalValueIndex() >= 0)
                {
                    DetectComplexPropertyChange(entryBase, complexProperty);
                }
                break;

            case INavigationBase navigation when propertyBase.GetRelationshipIndex() != -1:
                DetectNavigationChange(
                    entry as InternalEntityEntry ?? throw new UnreachableException("Complex type entry with a navigation"), navigation);
                break;
        }
    }

    private static void ThrowIfKeyChanged(IInternalEntry entry, IProperty property)
    {
        if (property.IsKey()
            && property.GetAfterSaveBehavior() == PropertySaveBehavior.Throw)
        {
            throw new InvalidOperationException(CoreStrings.KeyReadOnly(property.Name, entry.StructuralType.DisplayName()));
        }