예제 #1
0
        private static void Unfixup(INavigation navigation, InternalEntityEntry oldPrincipalEntry, InternalEntityEntry dependentEntry)
        {
            var dependentEntity = dependentEntry.Entity;

            if (navigation.IsDependentToPrincipal())
            {
                navigation.GetSetter().SetClrValue(dependentEntity, null);

                dependentEntry.SetRelationshipSnapshotValue(navigation, null);
            }
            else
            {
                if (navigation.IsCollection())
                {
                    var collectionAccessor = navigation.GetCollectionAccessor();
                    if (collectionAccessor.Contains(oldPrincipalEntry.Entity, dependentEntity))
                    {
                        collectionAccessor.Remove(oldPrincipalEntry.Entity, dependentEntity);
                        oldPrincipalEntry.RemoveFromCollectionSnapshot(navigation, dependentEntity);
                    }
                }
                else
                {
                    navigation.GetSetter().SetClrValue(oldPrincipalEntry.Entity, null);
                    oldPrincipalEntry.SetRelationshipSnapshotValue(navigation, null);
                }
            }
        }
예제 #2
0
 private static void SetNullForeignKey(InternalEntityEntry dependentEntry, IReadOnlyList <IProperty> dependentProperties)
 {
     foreach (var dependentProperty in dependentProperties)
     {
         dependentEntry[dependentProperty] = null;
         dependentEntry.SetRelationshipSnapshotValue(dependentProperty, null);
     }
 }
예제 #3
0
 private static void SetForeignKeyValue(IForeignKey foreignKey, InternalEntityEntry dependentEntry, IReadOnlyList <object> principalValues)
 {
     for (var i = 0; i < foreignKey.Properties.Count; i++)
     {
         var principalValue = principalValues[i];
         if ((foreignKey.Properties[i].GetGenerationProperty() == null) ||
             !foreignKey.PrincipalKey.Properties[i].ClrType.IsDefaultValue(principalValue))
         {
             var dependentProperty = foreignKey.Properties[i];
             dependentEntry[dependentProperty] = principalValue;
             dependentEntry.SetRelationshipSnapshotValue(dependentProperty, principalValue);
         }
     }
 }
예제 #4
0
        private static void StealReference(IForeignKey foreignKey, InternalEntityEntry dependentEntry)
        {
            var navigation = foreignKey.DependentToPrincipal;

            if (navigation != null)
            {
                navigation.GetSetter().SetClrValue(dependentEntry.Entity, null);
                dependentEntry.SetRelationshipSnapshotValue(navigation, null);
            }

            foreach (var property in foreignKey.Properties.Where(p => p.IsNullable).ToList())
            {
                dependentEntry[property] = null;
            }
        }
예제 #5
0
        private static void DoFixup(IEnumerable <INavigation> navigations, InternalEntityEntry principalEntry, InternalEntityEntry[] dependentEntries)
        {
            foreach (var navigation in navigations)
            {
                if (navigation.IsDependentToPrincipal())
                {
                    var setter = navigation.GetSetter();

                    foreach (var dependent in dependentEntries)
                    {
                        setter.SetClrValue(dependent.Entity, principalEntry.Entity);
                        dependent.SetRelationshipSnapshotValue(navigation, principalEntry.Entity);
                    }
                }
                else
                {
                    if (navigation.IsCollection())
                    {
                        var collectionAccessor = navigation.GetCollectionAccessor();

                        foreach (var dependent in dependentEntries)
                        {
                            var dependentEntity = dependent.Entity;
                            if (!collectionAccessor.Contains(principalEntry.Entity, dependentEntity))
                            {
                                collectionAccessor.Add(principalEntry.Entity, dependentEntity);
                                principalEntry.AddToCollectionSnapshot(navigation, dependentEntity);
                            }
                        }
                    }
                    else
                    {
                        // TODO: Decide how to handle case where multiple values match non-collection nav prop
                        // Issue #739
                        var value = dependentEntries.Single().Entity;
                        navigation.GetSetter().SetClrValue(principalEntry.Entity, value);
                        principalEntry.SetRelationshipSnapshotValue(navigation, value);
                    }
                }
            }
        }
예제 #6
0
        private static void DetectKeyChange(InternalEntityEntry entry, IProperty property)
        {
            var keys        = property.FindContainingKeys().ToList();
            var foreignKeys = property.FindContainingForeignKeys().ToList();

            if ((keys.Count > 0) ||
                (foreignKeys.Count > 0))
            {
                var snapshotValue = entry.GetRelationshipSnapshotValue(property);
                var currentValue  = entry[property];

                // Note that mutation of a byte[] key is not supported or detected, but two different instances
                // of byte[] with the same content must be detected as equal.
                if (!StructuralComparisons.StructuralEqualityComparer.Equals(currentValue, snapshotValue))
                {
                    var stateManager = entry.StateManager;

                    if (foreignKeys.Count > 0)
                    {
                        stateManager.Notify.ForeignKeyPropertyChanged(entry, property, snapshotValue, currentValue);

                        foreach (var foreignKey in foreignKeys)
                        {
                            stateManager.UpdateDependentMap(entry, foreignKey);
                        }
                    }

                    if (keys.Count > 0)
                    {
                        foreach (var key in keys)
                        {
                            stateManager.UpdateIdentityMap(entry, key);
                        }

                        stateManager.Notify.PrincipalKeyPropertyChanged(entry, property, snapshotValue, currentValue);
                    }

                    entry.SetRelationshipSnapshotValue(property, currentValue);
                }
            }
        }
예제 #7
0
        private void DetectNavigationChange(InternalEntityEntry entry, INavigation navigation)
        {
            var snapshotValue = entry.GetRelationshipSnapshotValue(navigation);
            var currentValue  = entry[navigation];
            var stateManager  = entry.StateManager;

            var added = new HashSet <object>(ReferenceEqualityComparer.Instance);

            if (navigation.IsCollection())
            {
                var snapshotCollection = (IEnumerable)snapshotValue;
                var currentCollection  = (IEnumerable)currentValue;

                var removed = new HashSet <object>(ReferenceEqualityComparer.Instance);
                if (snapshotCollection != null)
                {
                    foreach (var entity in snapshotCollection)
                    {
                        removed.Add(entity);
                    }
                }

                if (currentCollection != null)
                {
                    foreach (var entity in currentCollection)
                    {
                        if (!removed.Remove(entity))
                        {
                            added.Add(entity);
                        }
                    }
                }

                if (added.Any() ||
                    removed.Any())
                {
                    stateManager.Notify.NavigationCollectionChanged(entry, navigation, added, removed);

                    foreach (var addedEntity in added)
                    {
                        entry.AddToCollectionSnapshot(navigation, addedEntity);
                    }

                    foreach (var removedEntity in removed)
                    {
                        entry.RemoveFromCollectionSnapshot(navigation, removedEntity);
                    }
                }
            }
            else if (!ReferenceEquals(currentValue, snapshotValue))
            {
                stateManager.Notify.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue);

                if (currentValue != null)
                {
                    added.Add(currentValue);
                }

                entry.SetRelationshipSnapshotValue(navigation, currentValue);
            }

            foreach (var addedEntity in added)
            {
                var addedEntry = stateManager.GetOrCreateEntry(addedEntity);
                if (addedEntry.EntityState == EntityState.Detached)
                {
                    _attacher.AttachGraph(addedEntry, EntityState.Added);
                }
            }
        }