首页>Program>source

我有一个带有UI,业务(实体)和数据(DbContext)层的ASP.NET MVC3 web应用程序.我正在使用Entity Framework 4.1 Code First.现在,我要覆盖 DbContext.SaveChanges() 在数据层中,以便我可以设置 ModifiedDate 对实现我的 IAuditable的任何实体对象所做的所有更改 接口.我有一个静态的 DateProvider 返回 DateTime.Now的类和方法(GetCurrentDate) (除非我正在运行测试,在这种情况下,它将返回我告诉它的内容).

我想自动设置 ModifiedBy 以及当前用户的属性.这样做的最佳方法是什么? 框架中是否有内置的东西可以让我访问此信息,还是需要设置某种类似 DateProvider的东西? 类? 这是一个Active Directory环境,我们使用 WindowsAuthentication 在IIS中。

这是我的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();
}
最新回答
  • 2021-1-12
    1 #

    您可以使用 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();
       }
    }
    

  • 2021-1-12
    2 #

    我还想自动化我的MVC 4 / Entity Framework 5应用程序上的审核字段.我使用来自@Eranga的答案和此博客的信息:http://lourenco.co.za/blog/2013/07/audit-trails-concurrency-and-soft-deletion-with-entity-framework/使该方法有效 Ninject对我来说-在对其他人有value的情况下发布:

    创建了一个接口和抽象类:

    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; }
        ...
    }
    

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

    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://stackoverflow.com/a/3617961/1803682-注意,作为 MyDbContext 现在是请求范围,存储库也必须是

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

  • datetime:Python老化时间,第2部分:时区
  • PHP,从另一个php文件获取变量