// Use OnBeforeSaveChanges if all the values are known before actually saving the row -> saved at the same time as other entries private List <DataLogEntry> OnBeforeSaveChanges() { ChangeTracker.DetectChanges(); var dataLogEntries = new List <DataLogEntry>(); foreach (var entry in ChangeTracker.Entries()) { if (entry.Entity is DataLog || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged) { continue; } var dataLogEntry = new DataLogEntry(entry) { TableName = entry.Metadata.Name, ActionType = entry.State.ToString() }; dataLogEntries.Add(dataLogEntry); foreach (var property in entry.Properties) { if (property.IsTemporary) { // value will be generated by the database, get the value after saving dataLogEntry.TemporaryProperties.Add(property); continue; } string propertyName = property.Metadata.Name; if (property.Metadata.IsPrimaryKey()) { dataLogEntry.KeyValues[propertyName] = property.CurrentValue; continue; } switch (entry.State) { case EntityState.Added: dataLogEntry.NewValues[propertyName] = property.CurrentValue; break; case EntityState.Deleted: dataLogEntry.OldValues[propertyName] = property.OriginalValue; break; case EntityState.Modified: if (property.IsModified) { dataLogEntry.OldValues[propertyName] = property.OriginalValue; dataLogEntry.NewValues[propertyName] = property.CurrentValue; } break; } } } // Save dataLog entities that have all the modifications foreach (var dataLogEntry in dataLogEntries.Where(_ => !_.HasTemporaryProperties)) { DataLogs.Add(dataLogEntry.ToDataLog()); } // keep a list of entries where the value of some properties are unknown at this step return(dataLogEntries.Where(_ => _.HasTemporaryProperties).ToList()); }