/// <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 void Update(
            [NotNull] InternalEntityEntry entry,
            EntityState state,
            EntityState?oldState)
        {
            var mapKey     = entry.Entity ?? entry;
            var entityType = entry.EntityType;

            if (_hasSubMap &&
                entityType.HasDefiningNavigation())
            {
                if (_dependentTypeReferenceMap == null)
                {
                    _dependentTypeReferenceMap = new Dictionary <IEntityType, EntityReferenceMap>();
                }

                if (!_dependentTypeReferenceMap.TryGetValue(entityType, out var dependentMap))
                {
                    dependentMap = new EntityReferenceMap(hasSubMap: false);
                    _dependentTypeReferenceMap[entityType] = dependentMap;
                }

                dependentMap.Update(entry, state, oldState);
            }
            else
            {
                if (oldState.HasValue)
                {
                    Remove(mapKey, entityType, oldState.Value);
                }

                if (!oldState.HasValue ||
                    state != EntityState.Detached)
                {
                    switch (state)
                    {
                    case EntityState.Detached:
                        if (_detachedReferenceMap == null)
                        {
                            _detachedReferenceMap =
                                new Dictionary <object, InternalEntityEntry>(ReferenceEqualityComparer.Instance);
                        }

                        _detachedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Unchanged:
                        if (_unchangedReferenceMap == null)
                        {
                            _unchangedReferenceMap =
                                new Dictionary <object, InternalEntityEntry>(ReferenceEqualityComparer.Instance);
                        }

                        _unchangedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Deleted:
                        if (_deletedReferenceMap == null)
                        {
                            _deletedReferenceMap =
                                new Dictionary <object, InternalEntityEntry>(ReferenceEqualityComparer.Instance);
                        }

                        _deletedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Modified:
                        if (_modifiedReferenceMap == null)
                        {
                            _modifiedReferenceMap =
                                new Dictionary <object, InternalEntityEntry>(ReferenceEqualityComparer.Instance);
                        }

                        _modifiedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Added:
                        if (_addedReferenceMap == null)
                        {
                            _addedReferenceMap =
                                new Dictionary <object, InternalEntityEntry>(ReferenceEqualityComparer.Instance);
                        }

                        _addedReferenceMap[mapKey] = entry;
                        break;
                    }
                }
            }
        }
Exemple #2
0
        /// <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 void Update(
            InternalEntityEntry entry,
            EntityState state,
            EntityState?oldState)
        {
            var entityType = entry.EntityType;

            if (_hasSubMap &&
                entityType.HasSharedClrType)
            {
                if (_sharedTypeReferenceMap == null)
                {
                    _sharedTypeReferenceMap = new Dictionary <IEntityType, EntityReferenceMap>();
                }

                if (!_sharedTypeReferenceMap.TryGetValue(entityType, out var sharedMap))
                {
                    sharedMap = new EntityReferenceMap(hasSubMap: false);
                    _sharedTypeReferenceMap[entityType] = sharedMap;
                }

                sharedMap.Update(entry, state, oldState);
            }
            else
            {
                var mapKey = entry.Entity ?? entry;

                if (oldState.HasValue)
                {
                    Remove(mapKey, entityType, oldState.Value);
                }

                if (!oldState.HasValue ||
                    state != EntityState.Detached)
                {
                    switch (state)
                    {
                    case EntityState.Detached:
                        _detachedReferenceMap ??= new Dictionary <object, InternalEntityEntry>(LegacyReferenceEqualityComparer.Instance);
                        _detachedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Unchanged:
                        _unchangedReferenceMap ??=
                        new Dictionary <object, InternalEntityEntry>(LegacyReferenceEqualityComparer.Instance);
                        _unchangedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Deleted:
                        _deletedReferenceMap ??= new Dictionary <object, InternalEntityEntry>(LegacyReferenceEqualityComparer.Instance);
                        _deletedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Modified:
                        _modifiedReferenceMap ??= new Dictionary <object, InternalEntityEntry>(LegacyReferenceEqualityComparer.Instance);
                        _modifiedReferenceMap[mapKey] = entry;
                        break;

                    case EntityState.Added:
                        _addedReferenceMap ??= new Dictionary <object, InternalEntityEntry>(LegacyReferenceEqualityComparer.Instance);
                        _addedReferenceMap[mapKey] = entry;
                        break;
                    }
                }
            }
        }