1

我們映射的對象的主鍵是這樣的:NHibernate的ISession.Replicate與SQLite和本地ID生成

Id(x => x.Id, "ID").GeneratedBy.Native("SEQUENCENAME"); 

我們具有取決於特定的ID的業務邏輯存在(遺留,不容易改變)。新對象應該從Oracle序列中生成id,但總是有已知id的行。

我們使用SQLite進行單元測試,我需要用這些已知的ID將新對象保存到內存數據庫中。這不會有任何下列方法工作:

session.Replicate(objectWithKnownId, <any replication mode>); 
session.Merge(objectWithKnownId) 

據NHibernate的文檔中,Replicate方法似乎正是我要找的。

堅持所有可達瞬態 對象,重用當前 標識符值。

但是,當將它與SQLite一起使用時,我只會獲得生成的id。任何人都可以想出一個解決這個問題的好方法嗎?

回答

0

查看此問題並閱讀AlexCuse的回覆(對他的回答爲+1)後,我認爲在這種情況下無法使用本機ID生成器。我在測試設置中使用已知ID保存行時需要進行單元測試,並使用自動生成的ID插入測試。

一種選擇是有某種中,將在生產中使用的代碼GeneratedBy.Native("SEQUENCENAME")GeneratedBy.Assigned在測試流利的映射檢查,但我不喜歡有單元測試和生產之間的相關NHibernate的映射不同的想法。

我最終選擇的是在存儲庫中處理這個問題。我在相關的庫中的Add方法,如果ID尚未設置,這將處理分配從一個序列生成的ID,這樣的事情:

public void Add(TheClass newObject) { 
    if (newObject.Id == 0) { 
     newObject.Id = sequenceGenerator.GetNextValue("SEQUENCENAME"); 
    } 
    session.Save(newObject); 
} 

在單元測試中我將插入一個模擬序列發生器在存儲庫中。你可能會爭辯說,這與單元測試和生產代碼有不同映射的方法很相似,但我認爲這種方法使差別更加孤立。但最重要的原因是它允許我在單元測試中同時使用分配的和自動生成的ID。

1

我通常會針對運行應用程序的數據庫運行任何數據庫測試--SSQLite可以很好地進行快速測試,但它只是缺少很多在完整DBMS中可以找到的功能。如果它是映射問題,您可以使用類似here討論的方法在運行時調整映射。

你也可以用你需要的實體預加載一個SQLite數據庫,並且在你每次運行測試時複製它以供重用。這可能是我爲這樣的事情而採取的路線,但我無法提供任何有關如何做到這一點的技術細節。

老實說這聽起來有點怪讓你的業務邏輯依賴於某個ID的 - 我想你會希望它取決於某些實體 - 那麼你可以插入這些實體和存儲其生成的ID對測試的持續時間。

+0

感謝您的輸入。我同意,邏輯依賴於某些標識符似乎有點奇怪,但這是一個遺留數據庫,我無法改變這一點。 – 2011-02-10 07:35:17