public static IReadOnlyList <object> Deserialize(this DbContext context, IEntityEntryReader reader, ResolveConflict?resolveConflict = null) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (reader == null) { throw new ArgumentNullException(nameof(reader)); } var finder = new EntityEntryFinder(context); var synchronizer = new TemporaryIdentitySynchronizer( ); var entities = new List <object> ( ); var properties = new Dictionary <IProperty, object?> ( ); var collections = new List <CollectionEntry> ( ); while (reader.ReadEntry( )) { var entityType = reader.ReadEntityType(context.Model); var entityState = reader.ReadEntityState( ); properties.Clear( ); while (reader.ReadProperty(out var property, out var value)) { properties [property] = value; } var entityEntry = finder.FindOrCreate(entityType, properties); var conflict = resolveConflict != null && entityEntry.State != EntityState.Detached ? resolveConflict(entityEntry, entityState, properties) : ConflictResolution.OverwriteExistingEntry; if (conflict == ConflictResolution.KeepExistingEntry) { while (reader.ReadModifiedProperty(out _, out _)) { ; } while (reader.ReadNavigationState(out _)) { ; } entities.Add(entityEntry.Entity); continue; } foreach (var entry in properties) { var propertyEntry = entityEntry.SetProperty(entry.Key, entry.Value); if (propertyEntry.Metadata.IsConcurrencyToken) { // TODO: Check original version... } if (entityState != EntityState.Unchanged) { synchronizer.SynchronizeTemporaryIdentity(propertyEntry); } } entityEntry.SetState(entityState); while (reader.ReadModifiedProperty(out var property, out var value)) { entityEntry.SetModifiedProperty(property, value); } while (reader.ReadNavigationState(out var navigation)) { var collection = entityEntry.Collection(navigation); if (!collection.IsLoaded) { collections.Add(collection); } } entities.Add(entityEntry.Entity); } foreach (var collection in collections) { if (collection.CurrentValue == null) { collection.CurrentValue = (IEnumerable)collection.Metadata.GetCollectionAccessor( ).Create( ); } collection.IsLoaded = true; } return(entities.AsReadOnly( )); }
public static void AcceptChanges(this DbContext context, IEntityEntryReader reader) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (reader == null) { throw new ArgumentNullException(nameof(reader)); } var finder = new EntityEntryFinder(context); var properties = new Dictionary <IProperty, object?> ( ); while (reader.ReadEntry( )) { var entityType = reader.ReadEntityType(context.Model); var entityState = reader.ReadEntityState( ); properties.Clear( ); while (reader.ReadProperty(out var property, out var value)) { properties [property] = value; } var entityEntry = finder.Find(entityType, properties); if (entityEntry != null) { while (reader.ReadModifiedProperty(out var property, out var value)) { entityEntry.SetProperty(property, value); } } else { var modifiedProperties = new List <(IProperty Property, object?Value)> ( ); while (reader.ReadModifiedProperty(out var property, out var value)) { modifiedProperties.Add((property, value)); properties [property] = value; } entityEntry = finder.Find(entityType, properties); if (entityEntry != null) { foreach (var modified in modifiedProperties) { entityEntry.SetProperty(modified.Property, modified.Value); } } else { // TODO: Log entries not found } } while (reader.ReadNavigationState(out var navigation)) { ; } } context.ChangeTracker.AcceptAllChanges( ); }