Skip to content

Instantly share code, notes, and snippets.

@lancehilliard
Created October 20, 2018 01:50
Show Gist options
  • Save lancehilliard/0ef24a7c0fdd5007f5c197c4e9a0f37a to your computer and use it in GitHub Desktop.
Save lancehilliard/0ef24a7c0fdd5007f5c197c4e9a0f37a to your computer and use it in GitHub Desktop.
Basic SaveChanges() override for setting existing CreatedBy/CreatedUtc/LastModifiedBy/LastModifiedUtc columns on EF tables.
public partial class ExampleEntities {
private delegate void ColumnValueSetter(DbPropertyEntry entry, DateTimeOffset now);
private static readonly Dictionary<string, ColumnValueSetter> ControlledColumns = new Dictionary<string, ColumnValueSetter> {
{"CreatedBy", ColumnValueSetters.CreatedBy}
, {"CreatedUtc", ColumnValueSetters.CreatedUtc}
, {"LastModifiedBy", ColumnValueSetters.LastModifiedBy}
, {"LastModifiedUtc", ColumnValueSetters.LastModifiedUtc}
};
public override int SaveChanges() {
var modifiedEntries = ChangeTracker.Entries().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified);
var dateTimeOffsetUtcNow = DateTimeOffset.UtcNow;
foreach (var entry in modifiedEntries) {
foreach (var columnName in entry.CurrentValues.PropertyNames.Intersect(ControlledColumns.Keys)) {
ControlledColumns[columnName]((DbPropertyEntry)entry.Member(columnName), dateTimeOffsetUtcNow);
}
}
return base.SaveChanges();
}
public int SaveChangesWithoutOverridingAuditColumnValues() {
return base.SaveChanges();
}
private static class ColumnValueSetters {
private static readonly Func<object, ColumnValueSetter> GetColumnValueSetterForRecordInsert = initialValue => {
return (entry, now) => {
entry.CurrentValue = (entry.EntityEntry.State == EntityState.Added ? null : entry.OriginalValue) ?? initialValue;
};
};
public static readonly ColumnValueSetter CreatedBy = delegate (DbPropertyEntry entry, DateTimeOffset now) {
var columnValueSetter = GetColumnValueSetterForRecordInsert(Thread.CurrentPrincipal.Identity.Name);
columnValueSetter(entry, now);
};
public static readonly ColumnValueSetter CreatedUtc = delegate (DbPropertyEntry entry, DateTimeOffset now) {
var columnValueSetterForRecordInsert = GetColumnValueSetterForRecordInsert(now);
columnValueSetterForRecordInsert(entry, now);
};
public static readonly ColumnValueSetter LastModifiedBy = (entry, now) => entry.CurrentValue = Thread.CurrentPrincipal.Identity.Name;
public static readonly ColumnValueSetter LastModifiedUtc = (entry, now) => entry.CurrentValue = now;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment