2014-02-25 84 views
0

我想基於與POCO實體實體框架實現的撤銷/重做功能重做。因此,在我想跟蹤的每次更改之後,我都會調用ChangeTracker對實體進行任何修改,我將其稱爲ObjectStateManger以更改關係(即導航屬性)。我將所有的變化與當前值和以前的值一起存儲,以便能夠在歷史中來回查看。現在撤消/與實體框架更改跟蹤

我的問題是,對於具有導航屬性的實體和相應的外鍵這兩個值不正確,如果引用的實體是新加入的DbContext同步。

澄清:說我有這些類:

public class EntityFilter 
{ 
    [Key] 
    public Guid ID { get; set; } 

    public virtual ICollection<EntityConnection> IsSource { get; set; } 

    public virtual ICollection<EntityConnection> IsSink { get; set; } 

    //other stuff 
} 

public class EntityConnection 
{ 
    [Key] 
    public Guid SinkFilterID { get; set; } 

    [ForeignKey("SinkFilterID")] 
    public virtual EntityFilter Sink { get; set; } 

    public Guid SourceFilterID { get; set; } 

    [ForeignKey("SourceFilterID")] 
    public virtual EntityFilter Source { get; set; } 

    //more stuff 
} 

EntityConnection基本上是過濾器之間的許多一對多的關係,但它實際上包含了更多的領域這就是爲什麼我不能擺脫它。此外,我想盡可能通用,而不是依賴於我們的實際數據模型。

的問題出現了,如果我添加一個新的過濾器,然後將其連接到現有的過濾器(也可能是一個新的)。撤消連接仍然可以,但是當我嘗試重做我的程序會崩潰。在恢復的連接中,我可以看到外鍵SinkFilterID具有正確的值,但Sinknull(根據連接的方向,源可能發生同樣的情況)。手動呼叫DetectChanges沒有區別。在兩個現有的過濾器之間添加一個連接(即它們之前已經存儲在db中)是沒有問題的。

檢測到的此類新連接的更改僅包含ChangeTracker的實體更改,與ObjectStateManger沒有任何關係更改。我猜這是因爲這個關係已經被外鍵處理了,外鍵包含在PreviousValues的屬性中。

我讀過,在EntityState.Added國家實體獲取臨時密鑰而這種改變對他們跟蹤不完全支持。我能以某種方式獲得這個工作嗎?

我試着檢查MetadataWorkspace如果我更新的實體有一個外鍵和相應的導航屬性,並在這種情況下通過反射手動更新,但我不知道我實際上必須檢查什麼數據。

有沒有辦法外鍵和導航性能保持到添加實體同步?或者你有什麼建議可以嘗試?

非常感謝。

回答

0

這裏是我結束了:

我把所有添加的實體的單獨列表。然後,當我必須恢復由外鍵支持的導航屬性時,我會搜索該列表並手動設置導航屬性。最難的部分是弄清楚如何根據需要檢查數據模型並找到相應屬性的名稱。

整個系統仍具有最大的普遍性有些瑕疵,但它工作得很好正是我們需要的。