我試圖實現使用EF 4.1的審計日誌,通過如在以下地方討論重寫的SaveChanges()方法:實體框架的DbContext的SaveChanges()OriginalValue錯誤
- http://jmdority.wordpress.com/2011/07/20/using-entity-framework-4-1-dbcontext-change-tracking-for-audit-logging/
- Entity Framework 4.1 DbContext Override SaveChanges to Audit Property Change
雖然我遇到了「修改」條目的問題。無論何時我試圖獲取相關財產的原始價值,它始終與其在CurrentValue字段中的值相同。
我第一次使用此代碼,並將其成功地識別被修改的條目:
public int SaveChanges(string userID)
{
// Have tried both with and without the following line, and received same results:
// ChangeTracker.DetectChanges();
foreach (
var ent in this.ChangeTracker
.Entries()
.Where(p => p.State == System.Data.EntityState.Added
p.State == System.Data.EntityState.Deleted
p.State == System.Data.EntityState.Modified))
{
// For each change record, get the audit record entries and add them
foreach (AuditLog log in GetAuditRecordsForChange(ent, userID))
{
this.AuditLog.Add(log);
}
}
return base.SaveChanges();
}
的問題是在這(簡稱代碼):
private List<AuditLog> GetAuditRecordsForChange(DbEntityEntry dbEntry, string userID)
{
if (dbEntry.State == System.Data.EntityState.Modified)
{
foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
{
if (!object.Equals(dbEntry.OriginalValues.GetValue<object>(propertyName),
dbEntry.CurrentValues.GetValue<object>(propertyName)))
{
// It never makes it into this if block, even when
// the property has been updated.
}
// If I updated the property "Name" which was originally "OldName" to the value "NewName" and then break here and inspect the values by calling:
// ?dbEntry.OriginalValues.GetValue<object>("Name").ToString()
// the result will be "NewName" and not "OldName" as expected
}
}
}
奇怪的是,在這種情況下調用dbEntry.Property(propertyName).IsModified();
將 返回true。只是這個OriginalValue裏面沒有預期的值。任何人都願意幫助我指出正確的方向嗎?我似乎無法讓這個工作正常。
你是如何查詢你的實體,然後改變屬性值?如果你基本上是附加實體,然後將狀態設置爲修改,那麼原始值將會丟失。要保留原始值,您需要讓EF一直追蹤實體直到保存,否則您需要跟蹤自己代碼中的原始值。 – 2012-03-06 18:11:27
對不起 - 我試圖在評論中發佈一些代碼,但它運行不正常。我正在使用MVC控制器的[HttpPost]動作。這會調用我的產品存儲庫的「SaveProduct」方法。在存儲庫中,它看起來確實調用了'context.Entry(product).State = EntityState.Modified',然後我在上下文中調用SaveChanges。 你能指點我的任何資源來展示你提到的兩種技術嗎?或者至少給我幾個指點? – 2012-03-06 18:25:40
我在MVC中建議使用隱藏字段。基本上你會將你關心的原始值保存到隱藏的字段中,然後在POST中將它們讀回來。我不知道這方面的最佳做法,或者是否有MVC抽象幫助。 – 2012-03-06 18:40:32