实体框架6(代码优先)实体版本控制和审计

TK.*_*TK. 9 c# sql-server entity-framework entity-framework-6

我正在考虑将Entity Framework 6.1.1与SQL Server 2008 R2一起使用.

目前我正在使用代码优先EF功能创建我的模型和数据库.我的基本用例是创建一个特定实体的所有更改的日志(ID是关键列),以帮助审计员跟踪所做的所有更改以及由谁做出的更改.例如:

|ID|Version|Created Date|Created By|Modified Date|Modified By|Modify Action| ... (rest of entity fields)
-------------------------------------------------------------------------------------------------------
| 4| 12    | 12-Mar-14  | tom      | 20-Feb-15   | jack      | Update      |
| 4| 11    | 12-Mar-14  | tom      | 14-Feb-15   | jill      | Update      |
| 4| 1     | 12-Mar-14  | tom      | 12-Mar-14   | tom       | Create      |
Run Code Online (Sandbox Code Playgroud)

Entity Framework是否支持这种类型的数据库方案?如果是这样,我如何设置我的模型/解决方案以促进这一点?

我的另一个选择是拦截对SaveChanges()方法的所有调用DbContext并将所有数据库更改记录到一个单独的Audit表中,但这可能使检索信息更具挑战性.

任何有关使用SQL Server和EF 6创建审计跟踪的帮助都将非常感激.

mar*_*ith 7

我通过重载dbContext SaveChanges()方法使用了你提到的第二种方法:

public class MyContext : DbContext
{

 public int SaveChanges(int userId)
 {
    // Get all Added/Deleted/Modified entities (not Unmodified or Detached)
    foreach (var ent in this.ChangeTracker.Entries().Where(p => p.State ==  EntityState.Added 
    || p.State == EntityState.Deleted || p.State == EntityState.Modified))
    {

        foreach (AuditLog x in GetAuditRecordsForChange(ent, userId))
        {
            this.AuditLogs.Add(x);
        }
    }
    return base.SaveChanges();
  }
...
Run Code Online (Sandbox Code Playgroud)

因此,如果我想记录一个特定的实体,我只需调用重载的SaveChanges并传入UserId:

public void Update(StockCatalogueItem entity, int userId)
{
     _context.SaveChanges(userId);
}
Run Code Online (Sandbox Code Playgroud)

我还有一个自定义DoNotLog属性,我用它来装饰我不想记录的实体属性.如果没有这个,日志记录可能会生成大量数据,因为每个实体修改等于一个db条目.

[DoNotLog]
public int CreatedBy { get; set; }
Run Code Online (Sandbox Code Playgroud)

GetAuditRecordsForChange方法检查任何DoNotLog属性并返回List<AuditLog>保存在AuditLogs表中的属性:

public class AuditLog
    {
        public int Id { get; set; }
        public int CreatedBy { get; set; }
        public DateTime CreatedOn { get; set; }
        public AuditEventType EventType { get; set; }
        public string TableName { get; set; }
        public int EntityId { get; set; }
        public string ColumnName { get; set; }
        public string Controller { get; set; }
        public string Action { get; set; }
        public string IPAddress { get; set; }
        public string OriginalValue { get; set; }
        public string NewValue { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)