[英]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.