private bool TryGetDbSyncEntry(EntityKey key, IDictionary <EntityKey, DbSyncEntry> cache, out DbSyncEntry value) { if (cache.TryGetValue(key, out value)) { return(true); } if (!_source.ObjectStateManager.TryGetObjectStateEntry(key, out var source)) { return(false); } // try to load the entity first to populate the object state manager, if the object exists if (!_target.TryGetObjectByKey(key, out _) || !_target.ObjectStateManager.TryGetObjectStateEntry(key, out var target)) { return(false); } cache.Add(key, value = new DbSyncEntry(target.Entity, key) { SourceState = source.State, TargetState = target.State }); return(true); }
private static bool CanRefresh(DbSyncEntry entry) { switch (entry.TargetState) { case EntityState.Detached: return entry.SourceState == EntityState.Added; default: return true; } }
private void LoadModifiedEntityEntry(ObjectStateEntry source, IDictionary <EntityKey, DbSyncEntry> cache) { Contract.Assert(source.IsRelationship == false); Contract.Assert(source.State == EntityState.Modified); var entry = GetDbSyncEntry(source.EntityKey, cache); var entity = entry.TargetEntity; foreach (var property in source.GetModifiedProperties()) { entry.PropertiesInternal.Add(property, new DbSyncPropertyEntry(property) { CurrentValue = source.CurrentValues[property], OriginalValue = source.OriginalValues[property] }); } foreach (var reference in GetReferences(source).Where(reference => IsSourceReference(reference) && IsSourceReferenceChanged(source, reference))) { var property = GetNavigationProperty(GetEntityType(source), reference); if (property == null) { continue; } var currentKey = reference.EntityKey; var originalKey = GetEntityTypeKeyOriginalValue(source, reference); DbSyncEntry original = null; DbSyncEntry current = null; entry.ReferencesInternal.Add(property.Name, new DbSyncReferenceEntry(property.Name) { CurrentValue = currentKey != null && TryGetDbSyncEntry(currentKey, cache, out current) ? current.TargetEntity : null, OriginalValue = originalKey != null && TryGetDbSyncEntry(originalKey, cache, out original) ? original.TargetEntity : null }); var inverse = GetNavigationPropertyForTarget(reference); if (inverse == null) { continue; } if (original != null && (EntityState.Modified | EntityState.Unchanged).HasFlag(original.SourceState)) { switch (inverse.ToEndMember.RelationshipMultiplicity) { case RelationshipMultiplicity.Many: if (original.CollectionsInternal.TryGetValue(inverse.Name, out var collection)) { collection.OriginalValuesInternal.Add(entity); } else { original.CollectionsInternal.Add(inverse.Name, new DbSyncCollectionEntry(inverse.Name) { OriginalValuesInternal = { entity } }); } break; case RelationshipMultiplicity.One: case RelationshipMultiplicity.ZeroOrOne: if (original.ReferencesInternal.TryGetValue(inverse.Name, out var target)) { target.OriginalValue = entity; } else { original.ReferencesInternal.Add(inverse.Name, new DbSyncReferenceEntry(inverse.Name) { OriginalValue = entity }); } break; } } if (current != null && (EntityState.Modified | EntityState.Unchanged).HasFlag(current.SourceState)) { switch (inverse.ToEndMember.RelationshipMultiplicity) { case RelationshipMultiplicity.Many: if (current.CollectionsInternal.TryGetValue(inverse.Name, out var collection)) { collection.CurrentValuesInternal.Add(entity); } else { current.CollectionsInternal.Add(inverse.Name, new DbSyncCollectionEntry(inverse.Name) { CurrentValuesInternal = { entity } }); } break; case RelationshipMultiplicity.One: case RelationshipMultiplicity.ZeroOrOne: if (current.ReferencesInternal.TryGetValue(inverse.Name, out var target)) { target.OriginalValue = entity; } else { current.ReferencesInternal.Add(inverse.Name, new DbSyncReferenceEntry(inverse.Name) { OriginalValue = entity }); } break; } } } }