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

Code before:
/// </summary>
public partial class InternalEntryBase
{
    private struct InternalComplexCollectionEntry(InternalEntryBase entry, IComplexProperty complexCollection)
    {
        private List<InternalComplexEntry?>? _entries;
        private List<InternalComplexEntry?>? _originalEntries;
        private bool _isModified;
        private readonly InternalEntryBase _containingEntry = entry;
        private readonly IComplexProperty _complexCollection = complexCollection;

        /// <summary>
        ///     Attempts to get the count of a collection property, handling ArgumentOutOfRangeException
        ///     that may occur when the containing entry has an out-of-range ordinal during state transitions.
        ///     This can happen when deleting items from a complex collection that contains nested collections.
        /// </summary>
        private int TryGetCollectionCount(bool original)
        {
            try
            {
                var collection = original
                    ? (IList?)_containingEntry.GetOriginalValue(_complexCollection)
                    : (IList?)_containingEntry[_complexCollection];
                return collection?.Count ?? 0;
            }
            catch (ArgumentOutOfRangeException)
            {
                // When reading collection counts during state transitions, ArgumentOutOfRangeException can occur
                // if the containing entry is a complex entry with an out-of-range ordinal. This happens when:
                // 1. A complex collection item is being deleted
                // 2. That item contains nested collections or arrays
                // 3. EF tries to read those nested properties using the now-invalid ordinal
                // Returning 0 is safe because the entries list has already been initialized by previous operations.
                return 0;
            }
        }

        public List<InternalComplexEntry?> GetOrCreateEntries(
            bool original,
            EntityState defaultState = EntityState.Detached)
        {
            IList? collection;
            try
            {
                collection = original
                    ? (IList?)_containingEntry.GetOriginalValue(_complexCollection)
                    : (IList?)_containingEntry[_complexCollection];
            }
            catch (ArgumentOutOfRangeException)
            {
                // Out-of-range ordinal when reading collection during state transitions.

Review comment (bug):
@copilot This is an incorrect approach. You need to change the code that calculates the indices or expands the underlying collection

Code after:
/// </summary>
public partial class InternalEntryBase
{
    private struct InternalComplexCollectionEntry(InternalEntryBase entry, IComplexProperty complexCollection)
    {
        private static readonly bool UseOldBehavior37585 =
            AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37585", out var enabled) && enabled;

        private List<InternalComplexEntry?>? _entries;
        private List<InternalComplexEntry?>? _originalEntries;
        private bool _isModified;
        private readonly InternalEntryBase _containingEntry = entry;
        private readonly IComplexProperty _complexCollection = complexCollection;

        public List<InternalComplexEntry?> GetOrCreateEntries(
            bool original,
            EntityState defaultState = EntityState.Detached)
        {
            var collection = GetCollection(original);
            var entries = EnsureCapacity(collection?.Count ?? 0, original, trim: false);
            if (collection != null
                && defaultState != EntityState.Detached
                && (defaultState != EntityState.Deleted || original)
                && (defaultState != EntityState.Added || !original))
            {
                for (var i = 0; i < entries.Count; i++)
                {
                    if (entries[i] != null)
                    {
                        continue;
                    }

                    var targetState = defaultState;
                    var newEntry = new InternalComplexEntry((IRuntimeComplexType)_complexCollection.ComplexType, _containingEntry, i);
                    if (original)
                    {
                        var otherEntries = _entries;
                        if (defaultState != EntityState.Deleted
                            && otherEntries != null)
                        {
                            if (otherEntries.Count <= i || otherEntries[i] != null)
                            {
                                var nullIndex = otherEntries.FindIndex(e => e == null);
                                if (nullIndex >= 0)
                                {
                                    newEntry.Ordinal = nullIndex;
                                }
                                else
                                {
                                    targetState = EntityState.Deleted;
                                    newEntry.Ordinal = -1;