/// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual InternalEntityEntry TryGetEntry(object entity, bool throwOnNonUniqueness = true)
        {
            if (_entityReferenceMap.TryGetValue(entity, out var entry))
            {
                return(entry);
            }

            var type  = entity.GetType();
            var found = false;

            foreach (var keyValue in _dependentTypeReferenceMap)
            {
                // ReSharper disable once CheckForReferenceEqualityInstead.2
                if (Equals(keyValue.Key.ClrType, type) &&
                    keyValue.Value.TryGetValue(entity, out var foundEntry))
                {
                    if (found)
                    {
                        if (!throwOnNonUniqueness)
                        {
                            return(null);
                        }

                        throw new InvalidOperationException(
                                  CoreStrings.AmbiguousDependentEntity(
                                      entity.GetType().ShortDisplayName(),
                                      "." + nameof(EntityEntry.Reference) + "()." + nameof(ReferenceEntry.TargetEntry)));
                    }
                    entry = foundEntry;
                    found = true;
                }
            }

            return(entry);
        }
예제 #2
0
        public void Can_get_owned_entity_entry()
        {
            using (var context = new FixupContext())
            {
                var principal = new ParentPN {
                    Id = 77
                };
                var dependent = new ChildPN {
                    Name = "1"
                };
                principal.Child1 = dependent;
                principal.Child2 = dependent;

                Assert.Equal(
                    CoreStrings.UntrackedDependentEntity(
                        typeof(ChildPN).ShortDisplayName(),
                        "." + nameof(EntityEntry.Reference) + "()." + nameof(ReferenceEntry.TargetEntry)),
                    Assert.Throws <InvalidOperationException>(() => context.Entry(dependent)).Message);

                var dependentEntry1 = context.Entry(principal).Reference(p => p.Child1).TargetEntry;

                Assert.Same(dependentEntry1.GetInfrastructure(), context.Entry(dependent).GetInfrastructure());

                var dependentEntry2 = context.Entry(principal).Reference(p => p.Child2).TargetEntry;

                Assert.NotNull(dependentEntry2);
                Assert.Equal(
                    CoreStrings.AmbiguousDependentEntity(
                        typeof(ChildPN).ShortDisplayName(),
                        "." + nameof(EntityEntry.Reference) + "()." + nameof(ReferenceEntry.TargetEntry)),
                    Assert.Throws <InvalidOperationException>(() => context.Entry(dependent)).Message);
            }
        }
        /// <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 TryGet(
            [NotNull] object entity,
            [CanBeNull] IEntityType entityType,
            [CanBeNull] out InternalEntityEntry entry,
            bool throwOnNonUniqueness)
        {
            entry = null;
            var found = _unchangedReferenceMap?.TryGetValue(entity, out entry) == true ||
                        _modifiedReferenceMap?.TryGetValue(entity, out entry) == true ||
                        _addedReferenceMap?.TryGetValue(entity, out entry) == true ||
                        _deletedReferenceMap?.TryGetValue(entity, out entry) == true ||
                        _detachedReferenceMap?.TryGetValue(entity, out entry) == true;

            if (!found &&
                _hasSubMap &&
                _dependentTypeReferenceMap != null)
            {
                if (entityType != null)
                {
                    if (_dependentTypeReferenceMap.TryGetValue(entityType, out var subMap))
                    {
                        return(subMap.TryGet(entity, entityType, out entry, throwOnNonUniqueness));
                    }
                }
                else
                {
                    var type = entity.GetType();
                    foreach (var keyValue in _dependentTypeReferenceMap)
                    {
                        // ReSharper disable once CheckForReferenceEqualityInstead.2
                        if (keyValue.Key.ClrType.IsAssignableFrom(type) &&
                            keyValue.Value.TryGet(entity, entityType, out var foundEntry, throwOnNonUniqueness))
                        {
                            if (found)
                            {
                                if (!throwOnNonUniqueness)
                                {
                                    entry = null;
                                    return(false);
                                }

                                throw new InvalidOperationException(
                                          CoreStrings.AmbiguousDependentEntity(
                                              entity.GetType().ShortDisplayName(),
                                              "." + nameof(EntityEntry.Reference) + "()." + nameof(ReferenceEntry.TargetEntry)));
                            }

                            entry = foundEntry;
                            found = true;
                        }
                    }
                }
            }

            return(found);
        }