entity framework7审核日志

我正在将一个旧项目移植到ASP.NET 5和Entity Framework 7.我使用数据库第一种方法(DNX scaffold)来创建模型。

旧项目基于entity framework4,审计跟踪是通过覆盖DbContextSaveChanges方法实现的:

 public override int SaveChanges(System.Data.Objects.SaveOptions options) { int? UserId = null; if (System.Web.HttpContext.Current != null) UserId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); foreach (ObjectStateEntry entry in ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)) { Type EntityType = entry.Entity.GetType(); PropertyInfo pCreated = EntityType.GetProperty("Created"); PropertyInfo pCreatedById = EntityType.GetProperty("CreatedById"); PropertyInfo pModified = EntityType.GetProperty("Modified"); PropertyInfo pModifiedById = EntityType.GetProperty("ModifiedById"); if (entry.State == EntityState.Added) { if (pCreated != null) pCreated.SetValue(entry.Entity, DateTime.Now, new object[0]); if (pCreatedById != null && UserId != null) pCreatedById.SetValue(entry.Entity, UserId, new object[0]); } if (pModified != null) pModified.SetValue(entry.Entity, DateTime.Now, new object[0]); if (pModifiedById != null && UserId != null) pModifiedById.SetValue(entry.Entity, UserId, new object[0]); } } return base.SaveChanges(options); } 

我的问题是,我如何在Entity Framework 7中实现它? 我必须采用代码第一种方法吗?

基本上你有两种方法来实现这个目标:

使用ChangeTracker API(EF 6+):

这是我们目前在EF 6中的方式,它仍然有效并适用于EF 7:

首先,您必须确保您的实体正在为审计字段实现公共接口:

 public interface IAuditableEntity { int? CreatedById { get; set; } DateTime Created { get; set; } int? ModifiedById { get; set; } DateTime Modified { get; set; } } 

然后,您可以覆盖SaveChanges并使用审计值更新每个公共字段:

 public override int SaveChanges() { int? userId = null; if (System.Web.HttpContext.Current != null) userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); var modifiedEntries = ChangeTracker.Entries() .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); foreach (EntityEntry entry in modifiedEntries) { entry.Entity.ModifiedById = UserId; entry.Entity.Modified = DateTime.Now; if (entry.State == EntityState.Added) { entry.Entity.CreatedById = UserId; entry.Entity.Created = DateTime.Now; } } return base.SaveChanges(); } 

使用EF 7新的“阴影属性”function:

阴影属性是实体类中不存在的属性。 这些属性的值和状态仅在Change Tracker中维护。

换句话说,审核列不会在您的实体上公开,与上面的实体相比,它们似乎是一个更好的选择。

要实现阴影属性,首先必须在实体上配置它们。 比方说,你有一个需要有一些审计列的User对象:

 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().Property("CreatedById"); modelBuilder.Entity().Property("Created"); modelBuilder.Entity().Property("ModifiedById"); modelBuilder.Entity().Property("Modified"); } 

配置完成后,您现在可以在SaveChanges()覆盖上访问它们并相应地更新它们的值:

 public override int SaveChanges() { int? userId = null; if (System.Web.HttpContext.Current != null) userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); var modifiedBidEntries = ChangeTracker.Entries() .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); foreach (EntityEntry entry in modifiedBidEntries) { entry.Property("Modified").CurrentValue = DateTime.UtcNow; entry.Property("ModifiedById").CurrentValue = userId; if (entry.State == EntityState.Added) { entry.Property("Created").CurrentValue = DateTime.UtcNow; entry.Property("CreatedById").CurrentValue = userId; } } return base.SaveChanges(); } 

最后的想法:

为了实现像审计列这样的东西,我将采用Shadow Properties方法,因为这些是交叉关注的问题,并不一定属于我的域对象,因此以这种方式实现它们将使我的域对象保持良好和干净。

我在一个可能有帮助的图书馆工作过。

看看Audit.EntityFramework库,它拦截了SaveChanges()并与EF Core版本兼容。