簡體   English   中英

實體框架6(代碼優先)實體版本控制和審計

[英]Entity Framework 6 (code first) entity versioning and auditing

我正在考慮將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      |

Entity Framework是否支持這種類型的數據庫方案? 如果是這樣,我如何設置我的模型/解決方案以促進這一點?

我有另一種選擇是攔截對DbContext上的SaveChanges()方法的所有調用,並將所有數據庫更改記錄到一個單獨的Audit表中,但這可能會使檢索信息更具挑戰性。

任何有關使用SQL Server和EF 6創建審計跟蹤的幫助都將非常感激。

我通過重載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();
  }
...

因此,如果我想記錄一個特定的實體,我只需調用重載的SaveChanges並傳入UserId:

public void Update(StockCatalogueItem entity, int userId)
{
     _context.SaveChanges(userId);
}

我還有一個自定義的DoNotLog屬性,我用它來裝飾我不想記錄的實體屬性。 如果沒有這個,日志記錄可能會生成大量數據,因為每個實體修改等於一個db條目。

[DoNotLog]
public int CreatedBy { get; set; }

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

您可以查看Entity Framework Extended 它具有我用於將實體的所有更改記錄到XML的審計功能。 從文檔:

審核日志功能將在實體提交到數據庫時隨時捕獲對實體的更改。 審核日志僅捕獲已更改的實體,僅捕獲已更改的實體的屬性。 記錄前后值。 AuditLogger.LastAudit是保存此信息的位置,並且有一個ToXml()方法,可以輕松地將AuditLog轉換為xml以便於存儲。

可以通過實體上的屬性或通過Fluent配置API自定義AuditLog。

更新:

自2015年以來不再支持實體框架擴展。請參閱Entity Framework Plus以獲取此功能。

我想說這是DDD架構中提到的事件源模式的一個很好的候選者。 您永遠不會更改實體表,但始終插入。

這樣,當您需要特定版本時,您只需重新播放所有事件,並將它們應用於從版本0到您要查找的版本的實體。 可以使用實體快照解決可伸縮性問題。

第二種方法也是有效的。

參考: http//microservices.io/patterns/data/event-sourcing.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM