private void SetTrackingState(IHaveTrackingState entity) { if (entity == null) { return; } try { var state = entity.TrackingState; if (state == TrackingState.Added) { this.dbContext.Entry(entity).State = EntityState.Added; } if (state == TrackingState.Modified) { this.dbContext.Entry(entity).State = EntityState.Modified; } if (state == TrackingState.Deleted) { this.dbContext.Entry(entity).State = EntityState.Deleted; } entity.TrackingState = TrackingState.Unchanged; } catch (Exception ex) { throw ex; } }
private void FixState() { foreach (var entry in this.dbContext.ChangeTracker.Entries <IHaveTrackingState>()) { IHaveTrackingState stateInfo = entry.Entity; entry.State = this.ConvertState(stateInfo.TrackingState); stateInfo.TrackingState = TrackingState.Unchanged; } }
/// <summary> /// Traverse an object graph asynchronously to populate null reference properties. /// </summary> /// <param name="context">Used to query and save changes to a database</param> /// <param name="item">Object that implements IHaveTrackingState</param> public static async Task LoadRelatedEntitiesAsync(this DbContext context, IHaveTrackingState item) { await context.TraverseGraphAsync(item, async n => { if (n.Entry.State == EntityState.Detached) { n.Entry.State = EntityState.Unchanged; } foreach (var reference in n.Entry.References) { if (!reference.IsLoaded) { await reference.LoadAsync(); } } }); }
/// <summary> /// Traverse an object graph to populate null reference properties. /// </summary> /// <param name="context">Used to query and save changes to a database</param> /// <param name="item">Object that implements IHaveTrackingState</param> public static void LoadRelatedEntities(this DbContext context, IHaveTrackingState item) { context.TraverseGraph(item, n => { if (n.Entry.State == EntityState.Detached) { n.Entry.State = EntityState.Unchanged; } foreach (var reference in n.Entry.References) { if (!reference.IsLoaded) { reference.Load(); } } }); }
/// <summary> /// Set entity state to Detached for entities in an object graph. /// </summary> /// <param name="context">Used to query and save changes to a database</param> /// <param name="item">Object that implements IHaveTrackingState</param> public static void DetachEntities(this DbContext context, IHaveTrackingState item) { context.TraverseGraph(item, n => n.Entry.State = EntityState.Detached); }
public void ApplyChanges(IHaveTrackingState root) { ChangeTracker.TrackGraph(root, node => { if (!(node.Entry.Entity is IHaveTrackingState haveTrackingState)) { return; } node.Entry.State = EntityState.Detached; // Get related parent entity if (node.SourceEntry != null) { var relationship = node.InboundNavigation?.GetRelationshipType(); switch (relationship) { case RelationshipType.OneToOne: if (node.SourceEntry.State == EntityState.Added) { node.Entry.State = TrackingState.Added.ToEntityState(); } else if (node.SourceEntry.State == EntityState.Deleted) { node.Entry.State = TrackingState.Deleted.ToEntityState(); } else { node.Entry.State = haveTrackingState.TrackingState.ToEntityState(); } return; case RelationshipType.ManyToOne: if (node.SourceEntry.State == EntityState.Added) { node.Entry.State = TrackingState.Added.ToEntityState(); return; } var parent = node.SourceEntry.Entity as IHaveTrackingState; if (node.SourceEntry.State == EntityState.Deleted || parent?.TrackingState == TrackingState.Deleted) { try { node.Entry.State = TrackingState.Deleted.ToEntityState(); } catch (InvalidOperationException e) { throw new InvalidOperationException( @"An entity may not be marked as Deleted if it has related entities which are marked as Added. Remove added related entities before deleting a parent entity.", e); } return; } break; case RelationshipType.OneToMany: // If IHaveTrackingState is set deleted set entity state to unchanged, // since it may be related to other entities. if (haveTrackingState.TrackingState == TrackingState.Deleted) { node.Entry.State = TrackingState.Unchanged.ToEntityState(); return; } break; } } node.Entry.State = haveTrackingState.TrackingState.ToEntityState(); });