public override int SaveChanges() { ChangeTracker.DetectChanges(); foreach (var entry in ChangeTracker.Entries()) { bool ProcessBaseModel = true; if (entry.Entity.GetType().GetProperty("ProcessBaseModel") != null) { ProcessBaseModel = (bool)entry.Entity.GetType().GetProperty("ProcessBaseModel").GetValue(entry.Entity, null); } if (ProcessBaseModel) { if (entry.State == EntityState.Added) { if (entry.Entity.GetType().GetProperty("CreateTime") != null) { entry.Property("CreateTime").CurrentValue = DateTime.Now; } if (entry.Entity.GetType().GetProperty("CreatedBy") != null) { entry.Property("CreatedBy").CurrentValue = CurrentUserID; } } else if (entry.State == EntityState.Modified) { if (entry.Entity.GetType().GetProperty("UpdateTime") != null) { entry.Property("UpdateTime").CurrentValue = DateTime.Now; } if (entry.Entity.GetType().GetProperty("UpdatedBy") != null) { entry.Property("UpdatedBy").CurrentValue = CurrentUserID; } } } if (entry.Entity.GetType().GetProperty("CancelID") != null) { int?CancelIDOrginalValue = (int?)entry.Property("CancelID").OriginalValue; int?CancelIDCurrentValue = (int?)entry.Property("CancelID").CurrentValue; //Cancel durumu değiştiyse cancel alanlarını güncelle if (CancelIDOrginalValue != CancelIDCurrentValue) { if ((int?)entry.Property("CancelID").CurrentValue != null) { if (entry.Entity.GetType().GetProperty("CancelTime") != null) { entry.Property("CancelTime").CurrentValue = DateTime.Now; } if (entry.Entity.GetType().GetProperty("CanceledBy") != null) { entry.Property("CanceledBy").CurrentValue = CurrentUserID; } } else { if (entry.Entity.GetType().GetProperty("CancelTime") != null) { entry.Property("CancelTime").CurrentValue = null; } if (entry.Entity.GetType().GetProperty("CanceledBy") != null) { entry.Property("CanceledBy").CurrentValue = null; } } } } } //TODO: ElasticSearch vb. ile değişiklikleri logla return(base.SaveChanges()); }
private List <AuditEntry> OnBeforeSaveChanges() { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is AuditLog || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry(entry); auditEntry.TableName = entry.Metadata.Relational().TableName; auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { if (property.IsTemporary) { // value will be generated by the database, get the value after saving auditEntry.TemporaryProperties.Add(property); continue; } string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: auditEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.OldValues[propertyName] = property.OriginalValue; break; case EntityState.Modified: if (property.IsModified) { auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; } break; } } } // Save audit entities that have all the modifications foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties)) { AuditLog.Add(auditEntry.ToAudit()); } // keep a list of entries where the value of some properties are unknown at this step return(auditEntries.Where(_ => _.HasTemporaryProperties).ToList()); }
public override int SaveChanges() { ChangeTracker.DetectChanges(); return(base.SaveChanges()); }
public void Commit() { ChangeTracker.DetectChanges(); base.SaveChanges(); }
public override int SaveChanges() { ChangeTracker.DetectChanges(); AddTimeStamps <CreatedModifiedEntity>(); return(base.SaveChanges()); }
private List <AuditEntry> OnBeforeSaveChanges(string userId) { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry(entry); auditEntry.TableName = entry.Entity.GetType().Name; auditEntry.UserId = userId; auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { if (property.IsTemporary) { auditEntry.TemporaryProperties.Add(property); continue; } string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: auditEntry.AuditType = AuditType.Create; auditEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.AuditType = AuditType.Delete; auditEntry.OldValues[propertyName] = property.OriginalValue; break; case EntityState.Modified: if (property.IsModified) { auditEntry.ChangedColumns.Add(propertyName); auditEntry.AuditType = AuditType.Update; auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; } break; } } } foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties)) { AuditLogs.Add(auditEntry.ToAudit()); } return(auditEntries.Where(_ => _.HasTemporaryProperties).ToList()); }
private List <AuditEntry> OnBeforeSaveChanges() { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is Log || entry.Entity is AppUser || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry(entry, _httpContextAccessor); auditEntry.TableName = entry.Metadata.GetTableName(); auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { if (property.IsTemporary) { // value will be generated by the database, get the value after saving auditEntry.TemporaryProperties.Add(property); continue; } string propertyName = property.Metadata.Name; //if (property.Metadata.IsPrimaryKey()) //{ // auditEntry.KeyValues[propertyName] = property.CurrentValue; // continue; //} switch (entry.State) { //Pegar a opertação case EntityState.Added: auditEntry.Operacao = "Adição"; auditEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.Operacao = "Exclusão"; auditEntry.OldValues[propertyName] = property.OriginalValue; break; case EntityState.Modified: auditEntry.Operacao = "Atualização"; if (property.IsModified) { auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; } break; } } } // Save audit entities that have all the modifications foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties)) { Logs.Add(auditEntry.ToLog()); } // keep a list of entries where the value of some properties are unknown at this step return(auditEntries.Where(_ => _.HasTemporaryProperties).ToList()); }
public int SaveChangesWithNoAuditing() { ChangeTracker.DetectChanges(); return(base.SaveChanges()); }
public void Commit(TransactionInfo transactionInfo) { ChangeTracker.DetectChanges(); base.SaveChanges(); }
private int SaveChangesImpl(Person person, Tenant tenant, TransactionScope scope) { ChangeTracker.DetectChanges(); var dbEntityEntries = ChangeTracker.Entries().ToList(); var addedEntries = dbEntityEntries.Where(e => e.State == EntityState.Added).ToList(); var modifiedEntries = dbEntityEntries .Where(e => e.State == EntityState.Deleted || e.State == EntityState.Modified).ToList(); var tenantID = tenant.TenantID; SetTenantIDForAllModifiedEntries(dbEntityEntries, tenantID); // Project is such an important piece to PF; if we generate an audit log record that has a ProjectID, we need to update the last update date on the Project var distinctProjectIDsModified = new HashSet <int>(); foreach (var entry in modifiedEntries) { // For each changed record, get the audit record entries and add them var auditRecordsForChange = AuditLog.GetAuditLogRecordsForModifiedOrDeleted(entry, person, this, tenantID); AllAuditLogs.AddRange(auditRecordsForChange); ExtractProjectIDsFromAuditLogs(auditRecordsForChange).ForEach(x => distinctProjectIDsModified.Add(x)); } int changes; try { changes = base.SaveChanges(); } catch (DbEntityValidationException ex) { var sb = new StringBuilder(); foreach (var failure in ex.EntityValidationErrors) { sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType()); foreach (var error in failure.ValidationErrors) { sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage); sb.AppendLine(); } } throw new DbEntityValidationException( "Entity Validation Failed - errors follow:\n" + sb.ToString(), ex ); // Add the original exception as the innerException } foreach (var entry in addedEntries) { // For each added record, get the audit record entries and add them var auditRecordsForChange = AuditLog.GetAuditLogRecordsForAdded(entry, person, this, tenantID); AllAuditLogs.AddRange(auditRecordsForChange); ExtractProjectIDsFromAuditLogs(auditRecordsForChange).ForEach(x => distinctProjectIDsModified.Add(x)); } // now update LastUpdatedDate of any Projects that were touched if (distinctProjectIDsModified.Any()) { var listForLinqToSqlTranslation = distinctProjectIDsModified.ToList(); List <Project> projects = Projects.Where(x => listForLinqToSqlTranslation.Contains(x.ProjectID)).ToList(); foreach (var project in projects) { project.LastUpdatedDate = DateTime.Now; } ChangeTracker.DetectChanges(); } // we need to save the audit log entries now base.SaveChanges(); scope.Complete(); return(changes); }
private List <AuditEntry> OnBeforeSaveChanges() { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is Auditoria || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry(entry) { Tabela = entry.Metadata.Relational().TableName.ToUpper(), Usuario = _variables.UserName }; auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { if (property.IsTemporary) { auditEntry.TemporaryProperties.Add(property); continue; } string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.IdsAlterados[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: auditEntry.ValoresNovos[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.ValoresAntigos[propertyName] = property.OriginalValue; break; case EntityState.Modified: if (property.IsModified) { if ((property.CurrentValue != null && property.OriginalValue != null) && (!property.CurrentValue.Equals(property.OriginalValue))) { auditEntry.ValoresAntigos[propertyName] = property.OriginalValue; auditEntry.ValoresNovos[propertyName] = property.CurrentValue; } } break; } } } // Save audit entities that have all the modifications foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties)) { Auditoria.Add(auditEntry.ToAudit()); } // keep a list of entries where the value of some properties are unknown at this step return(auditEntries.Where(_ => _.HasTemporaryProperties).ToList()); }
public async Task <int> SaveChangesAsync() { ChangeTracker.DetectChanges(); return(await base.SaveChangesAsync().ConfigureAwait(false)); }
public List <AuditEntryBO> OnBeforeSaveChanges() { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntryBO>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is TblAuditHistory || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntryBO(entry); auditEntry.TableName = entry.Metadata.GetTableName(); auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { switch (property.Metadata.Name) { case "IsEnabled": property.CurrentValue = true; break; case "CreatedOn": if (entry.State == EntityState.Added) { property.CurrentValue = DateTime.Now; } break; case "ModifiedOn": property.CurrentValue = DateTime.Now; break; case "IsDeleted": property.CurrentValue ??= false; break; case "CreatedBy": property.CurrentValue ??= (long?)0m; break; default: break; } if (property.IsTemporary) { // value will be generated by the database, get the value after saving auditEntry.TemporaryProperties.Add(property); continue; } var propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: auditEntry.NewValues[propertyName] = property.CurrentValue; auditEntry.QueryAction = entry.State.ToString(); break; case EntityState.Deleted: auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.QueryAction = entry.State.ToString(); break; case EntityState.Modified: if (property.IsModified) { auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; auditEntry.QueryAction = entry.State.ToString(); } break; } } } // Save audit entities that have all the modifications foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties)) { TblAuditHistories.Add(auditEntry.ToAudit()); } // keep a list of entries where the value of some properties are unknown at this step return(auditEntries.Where(_ => _.HasTemporaryProperties).ToList()); }
private void OnBeforeSaveChanges(string userId) { ChangeTracker.DetectChanges(); foreach (var entry in ChangeTracker.Entries <AuditableEntity>()) { if (entry.State == EntityState.Added) { entry.Entity.CreatedById = userId; entry.Entity.CreatedOnUtc = DateTime.UtcNow; } else if (entry.State == EntityState.Modified) { entry.Entity.LastModifiedById = userId; entry.Entity.LastModifiedOnUtc = DateTime.UtcNow; } } var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry(entry); auditEntry.TableName = entry.Entity.GetType().Name; auditEntry.UserId = userId; auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: auditEntry.AuditType = AuditType.Create; auditEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.AuditType = AuditType.Delete; auditEntry.OldValues[propertyName] = property.OriginalValue; break; case EntityState.Modified: if (property.IsModified) { auditEntry.ChangedColumns.Add(propertyName); auditEntry.AuditType = AuditType.Update; auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; } break; } } } foreach (var auditEntry in auditEntries) { AuditLogs.Add(auditEntry.ToAudit()); } }
private void SaveChangesMetadataUpdate() { ChangeTracker.DetectChanges(); var now = DateTime.UtcNow; var currentUserName = $"{_userProvider.CurrentId}:{_userProvider.CurrentName}"; currentUserName = _userProvider.CurrentId.Length > 0 ? currentUserName : ""; var addedEntities = ChangeTracker.Entries().Where(x => x.State == EntityState.Added); foreach (var entityEntry in addedEntities) { if (!(entityEntry.Entity is IDomainEntityMetadata entityWithMetaData)) { continue; } if (entityEntry.Entity is IDomainEntitySoftUpdate softUpdateEntity && softUpdateEntity.MasterId != null) { softUpdateEntity.DeletedAt = now; softUpdateEntity.DeletedBy = currentUserName; continue; } entityWithMetaData.CreatedAt = now; entityWithMetaData.CreatedBy = currentUserName; entityWithMetaData.ChangedAt = entityWithMetaData.CreatedAt; entityWithMetaData.ChangedBy = entityWithMetaData.CreatedBy; } var updatedEntities = ChangeTracker.Entries().Where(x => x.State == EntityState.Modified); foreach (var entityEntry in updatedEntities) { if (!(entityEntry.Entity is IDomainEntityMetadata entityWithMetaData)) { continue; } entityWithMetaData.ChangedAt = now; entityWithMetaData.ChangedBy = currentUserName; if (entityEntry.Entity is IDomainEntitySoftUpdate) { continue; } entityEntry.Property(nameof(entityWithMetaData.CreatedAt)).IsModified = false; entityEntry.Property(nameof(entityWithMetaData.CreatedBy)).IsModified = false; } var deletedEntities = ChangeTracker.Entries().Where(x => x.State == EntityState.Deleted); foreach (var entityEntry in deletedEntities) { if (entityEntry.Entity is not IDomainEntitySoftDelete softDeleteEntity) { continue; } softDeleteEntity.DeletedAt = now; softDeleteEntity.DeletedBy = currentUserName; entityEntry.State = EntityState.Modified; } }
//TODO: add overrides for async methods private List <AuditEntry> OnBeforeSaving() { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); var dateTimeNow = DateTime.UtcNow; //TODO: check format foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is IAuditEntity auditEntity) { //ignore entities we don't want to add audit records for if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry { TableName = entry.Metadata.GetTableName(), DateTime = dateTimeNow }; foreach (var property in entry.Properties) { //for PK generated after save if (property.IsTemporary) { auditEntry.TemporaryProperties.Add(property); } string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } var createdBy = auditEntity.CreatedBy; var updatedBy = auditEntity.LastModifiedBy; auditEntry.EntityState = entry.State.ToString(); switch (entry.State) { case EntityState.Modified: auditEntity.LastModifiedAt = dateTimeNow; auditEntity.LastModifiedBy = updatedBy; if (property.IsModified) { auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; } break; case EntityState.Added: auditEntity.CreatedAt = dateTimeNow; auditEntity.CreatedBy = createdBy; auditEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.OldValues[propertyName] = property.OriginalValue; break; } } auditEntries.Add(auditEntry); } } foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties)) { Audits.Add(auditEntry.ToAudit()); } return(auditEntries.Where(_ => _.HasTemporaryProperties).ToList()); }
async Task <IEnumerable <(EntityEntry EntityEntry, Domain.Entities.Audit.Audit Audit)> > OnBeforeSaveChanges() { if (!_auditSettings.Enabled) { return(null); } ChangeTracker.DetectChanges(); var entitiesToTrack = ChangeTracker.Entries().Where( e => !(e.Entity is Domain.Entities.Audit.Audit) && e.State != EntityState.Detached && e.State != EntityState.Unchanged); foreach (var entityEntry in entitiesToTrack.Where(e => !e.Properties.Any(p => p.IsTemporary))) { var auditExcludedProps = entityEntry.Entity.GetType() .GetProperties() .Where( p => p.GetCustomAttributes( typeof(DoNotAudit), false).Any()) .Select(p => p.Name) .ToList(); await Audits.AddRangeAsync( new Domain.Entities.Audit.Audit { Table = entityEntry.Metadata.GetTableName(), Date = DateTime.Now.ToUniversalTime(), UserId = _currentUserService.Id, UserName = _currentUserService.Name, KeyValues = JsonSerializer.Serialize( entityEntry.Properties.Where(p => p.Metadata.IsPrimaryKey()).ToDictionary( p => p.Metadata.Name, p => p.CurrentValue)), NewValues = JsonSerializer.Serialize( entityEntry.Properties.Where( p => entityEntry.State == EntityState.Added || entityEntry.State == EntityState.Modified && !auditExcludedProps.Contains(p.Metadata.Name)) .ToDictionary( p => p.Metadata.Name, p => p.CurrentValue)), OldValues = JsonSerializer.Serialize( entityEntry.Properties.Where( p => entityEntry.State == EntityState.Deleted || entityEntry.State == EntityState.Modified && !auditExcludedProps.Contains(p.Metadata.Name)) .ToDictionary( p => p.Metadata.Name, p => p.OriginalValue)) }); } var returnList = new List <(EntityEntry EntityEntry, Domain.Entities.Audit.Audit Audit)>(); foreach (var entityEntry in entitiesToTrack.Where(e => e.Properties.Any(p => p.IsTemporary))) { var auditExcludedProps = entityEntry.Entity.GetType() .GetProperties() .Where( p => p.GetCustomAttributes( typeof(DoNotAudit), false).Any()) .Select(p => p.Name) .ToList(); returnList.Add( (entityEntry, new Domain.Entities.Audit.Audit { Table = entityEntry.Metadata.GetTableName(), Date = DateTime.Now.ToUniversalTime(), UserId = _currentUserService.Id, UserName = _currentUserService.Name, NewValues = JsonSerializer.Serialize( entityEntry.Properties.Where( p => !p.Metadata.IsPrimaryKey() && !auditExcludedProps.Contains(p.Metadata.Name)).ToDictionary( p => p.Metadata.Name, p => p.CurrentValue)) }
public override int SaveChanges() { ChangeTracker.DetectChanges(); updateUpdatedProperty <OrderDto>(); return(base.SaveChanges()); }
public void DetectAndSaveChanges() { ChangeTracker.DetectChanges(); SaveChanges(); }
public override Task <int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { ChangeTracker.DetectChanges(); updateUpdatedProperty <OrderDto>(); return(base.SaveChangesAsync(cancellationToken)); }
private IEnumerable <AuditEntry> OnBeforeSaveChanges([NotNull] string actionBy) { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.State == EntityState.Unchanged || entry.State == EntityState.Detached) { continue; } if (entry.Entity is IAuditableEntity auditable) { switch (entry.State) { case EntityState.Added: auditable.Created = DateTime.Now; auditable.CreatedBy = actionBy; break; case EntityState.Modified: auditable.Edited = DateTime.Now; auditable.EditedBy = actionBy; break; } } bool tmpSoftDelete = false; if (entry.Entity is ISoftDeleteEntity softDelete) { if (entry.State == EntityState.Deleted) { tmpSoftDelete = true; entry.State = EntityState.Modified; softDelete.IsDeleted = true; softDelete.Deleted = DateTime.Now; softDelete.DeletedBy = actionBy; } } if (entry.Entity.GetType().GetCustomAttribute <IgnoreAuditAttribute>() == null) { var auditEntry = new AuditEntry(entry) { ActionBy = actionBy }; auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { if (property.IsTemporary) { auditEntry.TemporaryProperties.Add(property); continue; } string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } if (property.Metadata.PropertyInfo.GetCustomAttribute <IgnoreAuditAttribute>() == null) { switch (entry.State) { case EntityState.Added: auditEntry.NewValues[propertyName] = property.CurrentValue; auditEntry.AuditType = AuditType.Create; break; case EntityState.Modified: if (property.IsModified) { auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; auditEntry.AuditType = tmpSoftDelete ? AuditType.Delete : AuditType.Update; auditEntry.ChangedColumns.Add(propertyName); } break; case EntityState.Deleted: auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.AuditType = AuditType.Delete; break; default: break; } } } } this.Audits.AddRange(auditEntries.Where(w => !w.HasTemporaryProperties).Select(s => s.ToAudit())); return(auditEntries.Where(w => w.HasTemporaryProperties)); } return(auditEntries); }
private void OnBeforeSaveChanges(string userId) { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry(entry) { TableName = entry.Entity.GetType().Name, UserId = userId }; auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { var propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: auditEntry.AuditType = AuditType.Create; auditEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.AuditType = AuditType.Delete; auditEntry.OldValues[propertyName] = property.OriginalValue; break; case EntityState.Modified: if (property.IsModified) { auditEntry.ChangedColumns.Add(propertyName); auditEntry.AuditType = AuditType.Update; auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; } break; case EntityState.Detached: break; case EntityState.Unchanged: break; default: throw new ArgumentOutOfRangeException(); } } } foreach (var auditEntry in auditEntries) { AuditLogs.Add(auditEntry.ToAudit()); } }
public override int SaveChanges() { ChangeTracker.DetectChanges(); UpdateProperties <UserToken>(); return(base.SaveChanges()); }
public override Task <int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)) { ChangeTracker.DetectChanges(); return(base.SaveChangesAsync(cancellationToken)); }
/// <summary> /// The event that triggers when /// the context savechanges method is called /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CurrentObjectContext_SavingChanges(object sender, EventArgs e) { try { ChangeTracker.DetectChanges(); // Important! System.Data.Entity.Core.Objects.ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext; List <System.Data.Entity.Core.Objects.ObjectStateEntry> objectStateEntryList = ctx.ObjectStateManager.GetObjectStateEntries(System.Data.Entity.EntityState.Added | System.Data.Entity.EntityState.Modified | System.Data.Entity.EntityState.Deleted) .ToList(); foreach (System.Data.Entity.Core.Objects.ObjectStateEntry entry in objectStateEntryList) { object[] list = entry.Entity.GetType().GetCustomAttributes(false); // Only the models that marked with 'Auditable' attribute will be tracked // Inside the model the properties that need to tracked needed to be marked with // Auditable attribute if (list.Count() == 0 || !((Nido.Common.Utilities.Attributes.AuditableAttribute)(list[0])).DoAudit) { continue; } TypeAttributes te = entry.Entity.GetType().Attributes; AuditTrail audit = new AuditTrail(); audit.RevisionStamp = DateTime.Now; audit.TableName = entry.EntitySet.Name + entry.EntityKey; audit.UserName = UserName; audit.SystemName = SystemName; if (!entry.IsRelationship) { switch (entry.State) { case System.Data.Entity.EntityState.Added: // write log... { audit.NewData = GetEntryValueInString(entry); audit.Actions = AuditActions.I.ToString(); } break; case System.Data.Entity.EntityState.Deleted: // write log... { audit.TablePrimaryId = GetKeyValue(entry); audit.OldData = GetEntryValueInString(entry); audit.Actions = AuditActions.D.ToString(); } break; case System.Data.Entity.EntityState.Modified: { string xmlOld = "<?xml version='1.0' encoding='utf-16'?> <" + (entry.EntitySet).Name + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"; string xmlNew = "<?xml version='1.0' encoding='utf-16'?> <" + (entry.EntitySet).Name + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"; PropertyInfo[] propList = entry.Entity.GetType().GetProperties(); Dictionary <string, object> attrList = new Dictionary <string, object>(); foreach (PropertyInfo pInfo in propList) { object[] atts = pInfo.GetCustomAttributes(typeof(AuditableAttribute), false); if (atts.Length > 0) { attrList.Add(pInfo.Name, atts[0]); } } int i = 0; object[] listte = entry.GetUpdatableOriginalValues()[0].GetType().GetCustomAttributes(false); foreach (string propertyName in entry.GetModifiedProperties()) { if (attrList.Keys.Contains(propertyName)) { DbDataRecord original = entry.OriginalValues; string oldValue = original.GetValue( original.GetOrdinal(propertyName)) .ToString(); System.Data.Entity.Core.Objects.CurrentValueRecord current = entry.CurrentValues; string newValue = current.GetValue( current.GetOrdinal(propertyName)) .ToString(); xmlOld += "<" + propertyName + " type='" + original.GetFieldType(i) + "'>" + oldValue + "</" + propertyName + ">"; xmlNew += "<" + propertyName + " type='" + original.GetFieldType(i) + "'>" + newValue + "</" + propertyName + ">"; } i++; } xmlOld += "</" + (entry.EntitySet).Name + ">"; xmlNew += "</" + (entry.EntitySet).Name + ">"; audit.OldData = xmlOld; audit.NewData = xmlNew; audit.TablePrimaryId = GetKeyValue(entry); audit.Actions = AuditActions.U.ToString(); break; } } } AuditTrails.Add(audit); } } catch { // Keep quite... } }
public override Task <int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken)) { ChangeTracker.DetectChanges(); return(base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken)); }
public void DetectChanges() { ChangeTracker.DetectChanges(); }
private List <Audit> OnBeforeSaveChanges() { UpdateAutoTrackedProperties(); ChangeTracker.DetectChanges(); var auditEntries = new List <Audit>(); foreach (var entry in ChangeTracker.Entries()) { if (!(entry.Entity is IAuditable)) { continue; } //handle CreatedDate ModifiedDate LastModifiedBy if ((entry.State == EntityState.Modified || entry.State == EntityState.Added || entry.State == EntityState.Deleted) && !(entry.Entity is Audit)) { var tableName = entry.Entity.GetType().Name; EntityStateChangeTypeEnum changeType = EntityStateChangeTypeEnum.Added; if (entry.State == EntityState.Deleted) { changeType = EntityStateChangeTypeEnum.Deleted; } //find the difference in original and current and use only foreach (var property in entry.OriginalValues.Properties) { var auditEntity = new Audit { User = _contextUser, Entity = tableName, DateTime = DateTime.Now }; changeType = EntityStateChangeTypeEnum.Added; auditEntity.EntityId = entry.CurrentValues != null ? entry.CurrentValues["Id"] as Guid? : Guid.NewGuid(); object orig = string.Empty; if (entry.State == EntityState.Modified) { changeType = EntityStateChangeTypeEnum.Modified; orig = entry.GetDatabaseValues().GetValue <object>(property.Name) ?? string.Empty; IAuditable curEntity; //if entity state is modified, then the createdDate does not need to be logged. if (property.Name == nameof(curEntity.CreatedDate)) { continue; } } var current = entry.CurrentValues != null && entry.CurrentValues[property.Name] != null ? entry.CurrentValues[property.Name]?.ToString() : string.Empty; if (!orig.ToString().Equals(current)) { //This routine modifies the relationship valus to brign Name in Name(Id) format. if (RelationshipMap.ContainsKey(property.Name) && !string.IsNullOrEmpty(current)) { var entityId = new Guid(current); var existing = ""; switch (property.Name) { case "CustomerId": existing = Customers.Where(p => p.Id == entityId) .Select(k => k.Name).FirstOrDefault(); break; case "ContactId": existing = Contacts.Where(p => p.Id == entityId) .Select(k => k.Name).FirstOrDefault(); break; } current = WrapNames(existing, current); } auditEntity.OldValue = string.IsNullOrEmpty(orig.ToString()) ? string.Empty : orig.ToString(); auditEntity.NewValue = current; auditEntity.ColumnName = property.Name; auditEntity.ChangeType = changeType; auditEntries.Add(auditEntity); } } } } return(auditEntries); }
public override int SaveChanges() { //int result = -1; DateTime eventDateTime = DateTime.Now; //string eventUser = HttpContext.Current.User.Identity.Name; User u = GetUserByLoginName(HttpContext.Current.User.Identity.Name.Split('\\').Last(), false); string eventUser = u.DisplayName; ChangeTracker.DetectChanges(); // Important! ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext; List <ObjectStateEntry> objectStateEntryList = ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Deleted) .ToList(); foreach (ObjectStateEntry entry in objectStateEntryList) { AuditEvent auditRecord = new AuditEvent(); auditRecord.EventDate = DateTime.Now; auditRecord.UserID = eventUser; if (entry.Entity == null) { continue; } string objModel = entry.Entity.ToString(); string[] objArray = objModel.Split('.'); string objType = objArray.Last();; if (objType.Contains("_")) { objType = objType.Substring(0, objType.IndexOf('_')); var testAuditType = this.AuditDescriptions.Where(a => a.AuditDescription.StartsWith(objType)); if (testAuditType.Count() == 0) { objType = entry.EntitySet.ToString(); } else { string newObjType = testAuditType.First().AuditDescription.ToString(); int spaceLoc = newObjType.IndexOf(' '); if (spaceLoc > 0) { objType = newObjType.Substring(0, spaceLoc); } } } if (!entry.IsRelationship && !objType.StartsWith("Audit") && objType != "EdmMetadata") { switch (entry.State) { case EntityState.Added: { //result = base.SaveChanges(); string objName = string.Format("{0} Added", objType); int AuditType = this.AuditDescriptions.Where(a => a.AuditDescription.ToLower() == objName.ToLower()).Take(1).Single().idAuditEventDescription; auditRecord.EventDescription = objName; auditRecord.idAuditEventDescription = AuditType; auditRecord.RecordChanged = entry.CurrentValues.GetValue(0).ToString(); try { int ord = entry.CurrentValues.GetOrdinal("tipstaffRecordID"); string value = entry.CurrentValues.GetValue(ord).ToString(); auditRecord.RecordAddedTo = Int32.Parse(value); } catch { try { int ord = entry.CurrentValues.GetOrdinal("warrantID"); string value = entry.CurrentValues.GetValue(ord).ToString(); auditRecord.RecordAddedTo = Int32.Parse(value); } catch { try { int ord = entry.CurrentValues.GetOrdinal("childAbductionID"); string value = entry.CurrentValues.GetValue(ord).ToString(); auditRecord.RecordAddedTo = Int32.Parse(value); } catch { auditRecord.RecordAddedTo = null; } } } break; } case EntityState.Deleted: { string objName = string.Format("{0} Deleted", objType); int AuditType = this.AuditDescriptions.Where(a => a.AuditDescription.ToLower() == objName.ToLower()).Take(1).Single().idAuditEventDescription; auditRecord.EventDescription = objName; auditRecord.idAuditEventDescription = AuditType; auditRecord.RecordChanged = entry.OriginalValues.GetValue(0).ToString(); try { int ord = entry.OriginalValues.GetOrdinal("tipstaffRecordID"); string value = entry.OriginalValues.GetValue(ord).ToString(); auditRecord.RecordAddedTo = Int32.Parse(value); } catch { try { int ord = entry.OriginalValues.GetOrdinal("warrantID"); string value = entry.OriginalValues.GetValue(ord).ToString(); auditRecord.RecordAddedTo = Int32.Parse(value); } catch { try { int ord = entry.OriginalValues.GetOrdinal("childAbductionID"); string value = entry.OriginalValues.GetValue(ord).ToString(); auditRecord.RecordAddedTo = Int32.Parse(value); } catch { auditRecord.RecordAddedTo = null; } } } // Iterate over the members (i.e. properties (including complex properties), references, collections) of the entity type List <AuditEventDataRow> data = new List <AuditEventDataRow>(); foreach (EdmMember member in entry.EntitySet.ElementType.Members) { string propertyName = member.Name.ToString(); DbPropertyValues oldData = this.Entry(entry.Entity).GetDatabaseValues(); string oldValue = ""; string newValue = "deleted"; try { oldValue = (oldData.GetValue <object>(propertyName) != null) ? oldData.GetValue <object>(propertyName).ToString() : "Empty"; if (oldValue == "") { oldValue = "Empty"; } } catch { oldValue = "Could not be mapped"; } if ((oldValue != newValue) && (oldValue != "Could not be mapped")) // probably not necessary { AuditEventDataRow newAuditRow = new AuditEventDataRow(); newAuditRow.ColumnName = propertyName; newAuditRow.Was = oldValue.Length <= 199 ? oldValue : oldValue.Substring(0, 199); newAuditRow.Now = newValue.Length <= 199 ? newValue : newValue.Substring(0, 199); data.Add(newAuditRow); } } if (data.Count() > 0) { auditRecord.AuditEventDataRows = data; } break; } case EntityState.Modified: { string objName = string.Format("{0} Amended", objType); int AuditType = this.AuditDescriptions.Where(a => a.AuditDescription.ToLower() == objName.ToLower()).Take(1).Single().idAuditEventDescription; auditRecord.EventDescription = objName; auditRecord.idAuditEventDescription = AuditType; auditRecord.RecordChanged = entry.CurrentValues.GetValue(0).ToString(); List <AuditEventDataRow> data = new List <AuditEventDataRow>(); foreach (string propertyName in entry.GetModifiedProperties()) { DbPropertyValues oldData = this.Entry(entry.Entity).GetDatabaseValues(); string oldValue = (oldData.GetValue <object>(propertyName) != null) ? oldData.GetValue <object>(propertyName).ToString() : "Empty"; if (oldValue == "") { oldValue = "Empty"; } CurrentValueRecord current = entry.CurrentValues; string newValue = (current.GetValue(current.GetOrdinal(propertyName)) != null) ? current.GetValue(current.GetOrdinal(propertyName)).ToString() : "Empty"; if (newValue == "") { newValue = "Empty"; } if (objType == "Template" && propertyName == "templateXML") { oldValue = "XML"; newValue = "XML - Too long to record new version"; } if (oldValue != newValue) // probably not necessary { AuditEventDataRow newAuditRow = new AuditEventDataRow(); newAuditRow.ColumnName = propertyName; newAuditRow.Was = oldValue.Length <= 199 ? oldValue : oldValue.Substring(0, 199); newAuditRow.Now = newValue.Length <= 199 ? newValue : newValue.Substring(0, 199); data.Add(newAuditRow); } } if (data.Count() > 0) { auditRecord.AuditEventDataRows = data; } break; } } } if (auditRecord.RecordChanged == "0" && auditRecord.RecordAddedTo == 0 && auditRecord.EventDescription.Contains("Added")) { //New TipstaffRecord derivative record added, so... //save the record base.SaveChanges(); //extract the new identity auditRecord.RecordChanged = entry.CurrentValues.GetValue(0).ToString(); //update the audit event this.AuditEvents.Add(auditRecord); //and savechanges at the end of the code block } else if (auditRecord.RecordChanged == "0" && auditRecord.RecordAddedTo != 0 && auditRecord.EventDescription.Contains("Added")) { //New record added, so... //save the record base.SaveChanges(); //extract the new identity auditRecord.RecordChanged = entry.CurrentValues.GetValue(0).ToString(); //update the audit event this.AuditEvents.Add(auditRecord); //and savechanges at the end of the code block } else if (auditRecord.RecordChanged != "0" && auditRecord.RecordChanged != null && (auditRecord.AuditEventDataRows != null && auditRecord.AuditEventDataRows.Count > 0)) { this.AuditEvents.Add(auditRecord); //base.SaveChanges(); } try { //base.SaveChanges(); //only uncomment for error handling } catch (DbEntityValidationException ex) { System.Diagnostics.Debug.Print(ex.Message); } catch (DbUpdateException ex) { System.Diagnostics.Debug.Print(ex.Message); } catch (Exception ex) { System.Diagnostics.Debug.Print(ex.Message); } } return(base.SaveChanges()); }
private List <AuditEntry> OnBeforeSaveChanges() { ChangeTracker.DetectChanges(); var auditEntries = new List <AuditEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var auditEntry = new AuditEntry(entry); auditEntry.TableName = entry.Metadata.GetTableName(); // EF Core 3.1: entry.Metadata.GetTableName(); auditEntries.Add(auditEntry); foreach (var property in entry.Properties) { // The following condition is ok with EF Core 2.2 onwards. // If you are using EF Core 2.1, you may need to change the following condition to support navigation properties: https://github.com/dotnet/efcore/issues/17700 // if (property.IsTemporary || (entry.State == EntityState.Added && property.Metadata.IsForeignKey())) if (property.IsTemporary) { // value will be generated by the database, get the value after saving auditEntry.TemporaryProperties.Add(property); continue; } string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { auditEntry.KeyValues[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: auditEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: auditEntry.OldValues[propertyName] = property.OriginalValue; break; case EntityState.Modified: if (property.IsModified) { auditEntry.OldValues[propertyName] = property.OriginalValue; auditEntry.NewValues[propertyName] = property.CurrentValue; } break; } } } // Save audit entities that have all the modifications foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties)) { Audits.Add(auditEntry.ToAudit()); } // keep a list of entries where the value of some properties are unknown at this step return(auditEntries.Where(_ => _.HasTemporaryProperties).ToList()); }