Track Created and Modified Fields Automatically with Entity Framework Code First
21-01-2019
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Web;
using log4net;
using TelifBandrolTutanak.Models;
namespace TelifBandrolTutanak.DAL
{
public class BandrolContext : DbContext
{
private readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public BandrolContext() : base("BandrolContext")
{
Database.Log = log => _logger.Debug(log);
}
public DbSet<User> Users { get; set; }
public override int SaveChanges()
{
AddUserCreatedAndModified();
/*var changed = ChangeTracker.Entries();
if (changed != null)
{
foreach (var entry in changed.Where(e => e.State == EntityState.Deleted))
{
entry.State = EntityState.Unchanged;
if (entry.Entity is ISoftDeletable)
{
((Base)entry.Entity).DeletedAt=DateTime.Now;
}
}
}
*/
return base.SaveChanges();
}
private void AddUserCreatedAndModified()
{
var entities = ChangeTracker.Entries().Where(x =>
x.Entity is Base && (x.State == EntityState.Added || x.State == EntityState.Modified));
var currentUsername = !string.IsNullOrEmpty(HttpContext.Current?.User?.Identity?.Name)
? HttpContext.Current.User.Identity.Name
: "Anonymous";
foreach (var entity in entities)
{
if (entity.State == EntityState.Added)
{
((Base) entity.Entity).CreatedAt = DateTime.Now;
((Base) entity.Entity).UserCreated = currentUsername;
}
else
{
if(entity.OriginalValues["CreatedAt"]!=null) ((Base) entity.Entity).CreatedAt = (DateTime) entity.OriginalValues["CreatedAt"];
if (entity.OriginalValues["UserCreated"]!=null) ((Base) entity.Entity).UserCreated = (string) entity.OriginalValues["UserCreated"];
}
((Base) entity.Entity).UpdatedAt = DateTime.Now;
((Base) entity.Entity).UserModified = currentUsername;
}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.Log = s => Debug.WriteLine(s);
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
public ObjectSet<TEntity> CreateObjectSet<TEntity>() where TEntity : class
{
var context = ((IObjectContextAdapter) this).ObjectContext;
return context.CreateObjectSet<TEntity>();
}
}
}