重写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);