2013-04-21 55 views
1

我一直在尋找所有,並找不到NHibernate的這個問題很好的答案。NHibernate身份插入

我正在使用一個使用NHibernate的API。我正在做一個數據傳輸,我試圖使用他們的用戶對象來保存用戶數據。

我創建對象

User objUser = new User(); 

他們有一個映射文件,指定的ID設置爲身份

<id name="Id" column="UserId" type="int"> 
    <generator class="native" /> 
</id> 

但我的要求之一是舊的標識保存到用戶表。我需要能夠臨時將身份插入設置爲ON並保存記錄,但仍然可以使用User對象來保存關聯的數據。

我試圖再次做這樣的事情

using (ISession session = MyDatabaseFactory.SessionFactory.OpenSession()) 
{ 
    using (ITransaction trans = session.BeginTransaction()) 
    { 
     session.CreateSQLQuery("SET IDENTITY_INSERT Users ON").UniqueResult(); 
     session.Save(objUser, objUser.Id); 
     session.Flush(); 

     trans.Commit(); 

     session.CreateSQLQuery("SET IDENTITY_INSERT Users OFF").UniqueResult(); 

     session.Close(); 
     objUser= session1.Merge(objUser); 
     } 
} 

而是試圖保存用戶對象時,後面類似這樣的

objUser.Passwords.Add("password1"); 
        objUser.Save() 

我得到一個錯誤:用同樣的標識值不同的對象是已經與會話相關聯

+0

這看起來像身份種子小於當前身份的情況。即下一個Id的種子爲0,但是您已經插入1而不是將種子設置爲1。 – Phill 2013-04-22 09:02:52

回答

0

Save()嘗試向數據庫插入新對象。 您應該嘗試Update(),它會更新數據庫中一個持久對象的現有記錄。 您也可以使用SaveOrUpdate(),它決定使用上述哪一個。

再次調用Save(),我認爲它試圖插入另一個具有相同ID的記錄。 The answer here有更多的細節。

0

如果您的要求僅適用於特殊情況,例如數據庫更新或遷移,你也許可以用不同的會話工廠,其中ID爲assigend工作:

<id name="Id" column="UserId" type="int"> 
    <generator class="assigned" /> 
</id> 

,並指定ID:

User objUser = new User() { UserId = 42 }; 

如果你的情況是緊密集成在正常的商業案例中,這不是一個很好的解決方案。

您可能會嘗試實施您自己的IIdentifierGenerator。不要期望它簡單直接。你可能有機會得到IdentityGenerator,合併Assigned生成器的一些代碼,並將這個SET IDENTITY_INSERT Users ON的東西插入到它中......生成器需要知道何時使用哪種策略。例如。當id仍然爲0時,讓SQL Server創建一個,當它是別的時候,插入指定的值。