/// <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); }
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); }