public async Task SaveChangesAsync(IIdentity user) { var contextInfo = GetContextInfo(user); _dbcontext.ChangeTracker.DetectChanges(); var entries = _dbcontext.ChangeTracker.Entries().ToList(); foreach (var entityChange in _dbcontext.ChangeTracker.Entries()) { var authResult = await AuthorizeEntityChangeAsync(user, entityChange); if (!authResult.HasSucceed) { if (entityChange.State == EntityState.Modified) { await Listen.ModificationFailedAsync(CreateWithValues(entityChange.OriginalValues), entityChange.Entity as T, GetContextInfo(user)); } else if (entityChange.State == EntityState.Deleted) { await Listen.RemoveFailedAsync(CreateWithValues(entityChange.OriginalValues), contextInfo); } throw new AuthorizationFailedException(authResult); } } // Added should be updated after saving changes for get the ID of the newly created entity var added = entries.Where(a => a.State == EntityState.Added).Select(a => a.Entity).ToList(); var modified = entries.Where(a => a.State == EntityState.Modified).Select(SelectBoth).ToList(); var removed = entries.Where(a => a.State == EntityState.Deleted).Select(a => SelectOriginal(a)).ToList(); if (removed.Any()) { if (GetLogicalDeleteProperty(_type) == null) { if (!IgnoreLogicalDeleteError && removed.Any(entry => GetLogicalDeleteProperty(entry.GetType()) != null)) { throw new LogicalSecurityRiskException( $"There are derived types in the deleted entries which have LogicalDeleteAttribute, but the base type does not use logical delete."); } } else { var logicalRemoved = entries.Where(a => a.State == EntityState.Deleted).ToList(); logicalRemoved.ForEach(entry => { entry.Reload(); entry.State = EntityState.Modified; entry.Property(GetLogicalDeleteProperty(_type).Name).CurrentValue = true; }); } } await _dbcontext.SaveChangesAsync(); await DistributeToListenersAsync(added, contextInfo, modified, removed); }
public async Task RemoveFailed() { MockListener.Reset(); await Listen.RemoveFailedAsync(ent, ctx); Assert.IsFalse(MockListener.WasOnCreatedCalled); Assert.IsFalse(MockListener.WasOnCreationValidationFailedCalled); Assert.IsFalse(MockListener.WasOnModifiedCalled); Assert.IsFalse(MockListener.WasOnModificationFailedCalled); Assert.IsFalse(MockListener.WasOnDeletedCalled); Assert.IsTrue(MockListener.WasOnDeletionFailedCalled); }