2016-05-04 65 views
2

出於審計原因,我重寫了SaveChanges函數。但是,我想捕捉原始對象(即人物)的原始值和當前值,以便我可以序列化前後兩者。從Entity Framework的SaveChanges函數獲取原始對象?

Public Overrides Function SaveChanges() As Integer 

    ChangeTracker.DetectChanges() 
    Dim ctx As ObjectContext = DirectCast(Me, IObjectContextAdapter).ObjectContext 

    Dim objectStateEntryList As List(Of ObjectStateEntry) = ctx.ObjectStateManager. 
     GetObjectStateEntries(EntityState.Added Or EntityState.Modified Or EntityState.Deleted).ToList() 

    For Each ent As ObjectStateEntry In objectStateEntryList 
     If Not ent.IsRelationship Then 
      Dim objectType As Type = ObjectContext.GetObjectType(ent.Entity.GetType) 
      Dim audit As New Audit With { 
       .ObjectId = ent.EntityKey.EntityKeyValues.First.Value, 
       .ObjectType = ObjectContext.GetObjectType(ent.Entity.GetType).Name, 
       .User = (From u In Users Where u.Username = My.User.Name).First 
      } 
      With audit 
       Select Case ent.State 
        Case EntityState.Added 
         .Action = "Created" 
         .Detail = "Record created" 
        Case EntityState.Deleted 
         .Action = "Deleted" 
         .Detail = "Record deleted" 
        Case EntityState.Modified 
         Dim newObj As String = SerializeToString(
          Convert.ChangeType(ent.Entity, objectType) 
         ) 
         .Action = "Modified" 
         .Detail = newObj.ToString 
       End Select 
      End With 
     End If 
    Next 

    Return MyBase.SaveChanges() 

End Function 

這就是我得到了多少,但當我嘗試和ChangeType它拋出「對象必須實現IConvertible」。

+0

什麼是SerializeToString,它爲什麼關心你傳遞給它的類型?另外,爲什麼不爲你的序列化程序使用JSON.NET? –

+0

@JonathanAllen這只是我使用XmlSerializer編寫的函數,然後將xml作爲字符串返回,以便我可以存儲它。我沒有使用JSON.NET,因爲我想將它作爲XML存儲。 –

+0

啊,是的,那個老問題。我現在看到爲什麼你想要調用ChangeType,儘管它沒有做你認爲它的作用。 –

回答

0

我上一次跟蹤每一項變更所需的項目時,我們使用了一個歷史表和一個ON UPDATE觸發器。更改數據會激發觸發器,然後觸發器會將原始行復制到歷史記錄表中。

這是100%EF兼容,但您需要爲每個表單獨設置它。

+0

有道理,這個項目的模式非常大,但它可能不是最好的主意。我想解決這個問題的方法是序列化對象並存儲它,以便只需要一個單獨的表。我不能相信在SaveChanges()函數中檢索對象與原始類型很難。 –

0

這並不完全回答你的主要問題,但可能會幫助你改進審計。

免責聲明:我的項目Entity Framework Plus

的主人,我建議你看一下我們的EF+ Audit Feature,所有審計信息可以很容易地使用這個庫檢索。

// using Z.EntityFramework.Plus; // Don't forget to include this. 

var ctx = new EntityContext(); 
// ... ctx changes ... 

var audit = new Audit(); 
audit.CreatedBy = "ZZZ Projects"; // Optional 
ctx.SaveChanges(audit); 

// Access to all auditing information 
var entries = audit.Entries; 
foreach(var entry in entries) 
{ 
    foreach(var property in entry.Properties) 
    { 
    } 
} 


// CALL your serializer here 
SerializeToString(entries, ...); 

該代碼是開源的。

相關問題