2009-08-26 134 views
0

我怎樣才能讓NHibernate的這種behaviuor:實現NHibernate的更新實體副本

有一個叫用戶的實體在我的域名

// I ommit mapping attributes 
public class User 
{ 
    int Id {get; set;} 
    int pId {get; set;} 
    //....other props, such as Login, Name, email... 
} 

我需要它的完整副本,更新的時候。必須將pId設置爲原始ID。舊實體必須保持原樣。

因此,這必須像某些版本控制系統,其中pId - 是不可變的身份,Id - 就像版本。我試圖使用版本映射屬性,但它只是更新版本字段,重新創建完整的實體。什麼方法會更好?

回答

1

我爲我們的應用程序編寫了一個版本控制系統。我將版本化的對象分成兩個類,一個代表整個對象,另一個代表其版本。

在我們的軟件中,版本控制是業務邏輯的一部分。應用程序提供對歷史的訪問,用戶可以對版本控制進行一些控制。

因此在內存中創建新版本。您需要執行深層複製。您可以通過在根實體及其所有子項中實現接口來實現此目的。該接口提供了一種方法DeepCopy,該方法通過對象圖遞歸調用。

object還有一個受保護的MemberwiseCopy方法,這可能會有所幫助。它不是一個深層次的副本。

我們不想讓痛苦去維護複製每一個屬性的代碼。因此,我們使用序列在內存中拷貝的對象圖:

public static T CopyDataContract<T>(T obj) 
{ 
    NetDataContractSerializer serializer = new NetDataContractSerializer(); 
    using (MemoryStream stream = new MemoryStream()) 
    { 
     serializer.Serialize(stream, obj); 
     stream.Position = 0; 
     return (T)serializer.Deserialize(stream); 
    } 
} 

此外,我們在其中重置ID的實體的方法和做一些其他清理。這也是通過對象圖遞歸地完成的。

現在,它工作正常。在未來,我們可能需要將其重構爲接口實現,該實現稍微清晰一些。

0

根據歷史是否不屬於你的域邏輯,我建議使用觸發器。通過不屬於域邏輯的一部分,我的意思是 - 你不需要向用戶展示它,你不會從歷史版本中複製副本。

通過使用觸發器,您有幾個選擇 - 最簡單的(並且暗示您確實需要僅爲少數表保存歷史記錄) - 將具有單獨的_history表,它是您原始表的副本。

總而言之,這取決於你究竟是什麼。