2011-10-07 76 views
1

對於大多數CRUD應用程序,我使用NHibernate的guid.comb ID生成器。這樣做的好處是,在我刷新數據庫之前,我可以訪問該ID並解決與使用常規Guid相關的索引碎片問題。使用NServiceBus時NHibernate ID生成器

當我們推出短信它提出了幾個問題:

  1. 因爲我們正在發送命令來修改我們的領域層,我們實際上並沒有獲得「新」的域對象的UI 。通常(在Web應用程序的情況下),我們需要它的標識符來重定向到另一個頁面。一種解決方案是將id作爲命令的一部分(例如Guid.NewGuid())傳遞,但是我們失去了NHibernate提供的順序Guid。
  2. 如果我們改爲使用身份策略,我們會刪除索引問題,但現在沒有簡單的方法來確定用戶界面中的ID,除了訂閱事件或同步執行他的命令外,兩者在網絡中都不理想應用。

所以我很好奇其他NServiceBus開發者正在採取什麼策略。在現有的實體上執行一些操作並不是一個真正的問題,因爲我們可以使用ajax發送請求來發送命令,並通知用戶一切都很成功(可能)。由於他們所在的頁面已經有了更新的信息,這就足夠了。

然而,當我們創建一個域對象(通過命令)的一個新實例,我們經常需要將用戶重定向到一個頁面,然後檢索從我們的數據庫新創建的實體。當然,這個實體可能還沒有被保存(因爲我們正在處理我們的命令異步),我們通常需要一個Id來執行此重定向。

+0

你能解釋一下多一點的工作流程?看起來好像你正在追蹤一個「會話」。通常這是通過客戶端生成的id完成的,並且與實體ID無關。 –

+0

@AdamFyles這是一個相當常見的Web應用程序工作流程。有某種「創建」頁面可將某些內容保存到數據庫,然後將您重定向到該項目的「編輯」頁面。 –

+0

我只是感覺到工作流程。我會在客戶端生成一個id,並且除了您的實體ID之外還要帶上這個id。 –

回答

1

這是nhibernate用於生成梳子的代碼。

private Guid Generate() 
    { 
     byte[] guidArray = Guid.NewGuid().ToByteArray(); 

     DateTime baseDate = new DateTime(1900, 1, 1); 
     DateTime now = DateTime.Now; 

     // Get the days and milliseconds which will be used to build the byte string 
     TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks); 
     TimeSpan msecs = now.TimeOfDay; 

     // Convert to a byte array 
     // SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 
     byte[] daysArray = BitConverter.GetBytes(days.Days); 
     byte[] msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds/3.333333)); 

     // Reverse the bytes to match SQL Servers ordering 
     Array.Reverse(daysArray); 
     Array.Reverse(msecsArray); 

     // Copy the bytes into the guid 
     Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2); 
     Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4); 

     return new Guid(guidArray); 
    } 

也許你可以使用它:)