重写SaveChanges并设置ModifiedDate,但是如何设置ModifiedBy?

我有一个ASP.NET MVC3 Web应用程序与UI,商业(实体)和数据(DbContext)层。 我正在使用entity framework4.1代码优先。 现在,我重写了Data层中的DbContext.SaveChanges() ,这样我就可以为ModifiedDate设置对实现我的IAuditable接口的任何实体对象所做的所有更改。 我有一个静态的DateProvider类和方法(GetCurrentDate),返回DateTime.Now (除非我正在运行一个testing,在这种情况下,它返回任何我告诉它)。

我想自动将ModifiedBy属性设置为当前用户。 什么是最好的方式去做这个? 在框架中是否有内容可以让我访问这些信息,或者是否需要设置类似于DateProvider类的东西? 这是一个Active Directory环境,我们在IIS中使用WindowsAuthentication

这是我的SaveChanges代码:

 public override int SaveChanges() { var changeSet = ChangeTracker.Entries<IAuditable>(); if (changeSet != null) { foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged)) { entry.Entity.ModifiedDate = DateProvider.GetCurrentDate(); } } return base.SaveChanges(); } 

您可以使用HttpContext.Current.User.Identity.Name来获取当前用户的名称。

 public override int SaveChanges() { var changeSet = ChangeTracker.Entries<IAuditable>(); if (changeSet != null) { foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged)) { entry.Entity.ModifiedDate = DateProvider.GetCurrentDate(); entry.Entity.ModifiedBy = HttpContext.Current.User.Identity.Name; } } return base.SaveChanges(); } 

更好的方法是使用构造函数注入来将当前用户传递给上下文

 public class MyContext : DbContext { public MyContext(string userName) { UserName = userName; } public string UserName { get; private set; } public override int SaveChanges() { var changeSet = ChangeTracker.Entries<IAuditable>(); if (changeSet != null) { foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged)) { entry.Entity.ModifiedDate = DateProvider.GetCurrentDate(); entry.Entity.ModifiedBy = UserName; } } return base.SaveChanges(); } } 

我也想在我的MVC 4 / Entity Framework 5应用程序中自动化审计字段的人口。 我使用@ Eranga的答案和这个博客的信息: http ://lourenco.co.za/blog/2013/07/audit-trails-concurrency-and-soft-deletion-with-entity-framework/使这种方法工作对于我与Ninject – 张贴有价值的任何人:

创build一个接口和抽象类:

 public interface IAuditableEntity { DateTime? CreatedDate { get; set; } string CreatedBy { get; set; } DateTime? LastModifiedDate { get; set; } string LastModifiedBy { get; set; } } public abstract class AuditableEntity:IAuditableEntity { public DateTime? CreatedDate { get; set; } public string CreatedBy { get; set; } public DateTime? LastModifiedDate { get; set; } public string LastModifiedBy { get; set; } } 

在我的实体中使用它们:

 public class DataEntity : AuditableEntity { public int DataEntityID { get; set; } ... } 

添加了一个接受HttpContext并覆盖SaveChanges的MyDbContext的构造函数:

 public EFDbContext(HttpContext context) { _context = context; } public HttpContext _context { get; private set; } public override int SaveChanges() { DateTime currentDateTime = DateTime.Now; foreach (var auditableEntity in ChangeTracker.Entries<IAuditableEntity>()) { if (auditableEntity.State == EntityState.Added || auditableEntity.State == EntityState.Modified) { auditableEntity.Entity.LastModifiedDate = currentDateTime; switch (auditableEntity.State) { case EntityState.Added: auditableEntity.Entity.CreatedDate = currentDateTime; auditableEntity.Entity.CreatedBy = _context.User.Identity.Name; break; case EntityState.Modified: auditableEntity.Entity.LastModifiedDate = currentDateTime; auditableEntity.Entity.LastModifiedBy = _context.User.Identity.Name; if (auditableEntity.Property(p => p.CreatedDate).IsModified || auditableEntity.Property(p => p.CreatedBy).IsModified) { throw new DbEntityValidationException(string.Format("Attempt to change created audit trails on a modified {0}", auditableEntity.Entity.GetType().FullName)); } break; } } } return base.SaveChanges(); } 

最后 – 需要每个请求都有一个DbContext,并根据下面的回答传递HttpContext: https : MyDbContext – 请注意,由于MyDbContext现在是请求范围,所以存储库也必须如此。

 kernel.Bind<IDataRepository>() .To<EFDataRepository>() .InRequestScope(); kernel.Bind<MyDbContext>().ToSelf() .InRequestScope() .WithConstructorArgument("context", ninjectContext=>HttpContext.Current);