2012-10-03 61 views
0

在將整個系統從NH1.2升級到NH3.3的過程中。 系統中的一個常見場景(由以前的開發人員)是分離多個對象並將它們存儲在Web Session中,然後通過IHttpModule在每個請求上附加它們。NH3.3和附着分離物體

在一個簡單的頁面加載,運行NHProf,我注意到這些對象現在被連接正在觸發它們在數據庫中被更新,儘管它們沒有被改變。

以前的代碼(NH1.2)附加沿的線條:

 
if (((NHibernate.Impl.SessionImpl)session).IsSaved(obj) 
    session.Lock(obj, LockMode.None) 

因爲它似乎IsSaved已被刪除的代碼是現在:

 
if (obj != null) 
    session.Lock(obj, LockMode.None) 

我的理解是LockMode沒有人不應該導致數據庫更新。 一些對象有版本,其他則沒有。兩個正在更新。

任何意見表示讚賞。

+0

難道這是鎖如果實際上應該做什麼,但通過IHttpModule關閉會話後,NH正在更新數據庫,就像先前分離的對象現在在會話中 - 儘管它們還沒有被更改過? – TheITGuy

回答

0

我想我會通過一個比喻解釋,看到了差距:

var obj = _nhibernateSession.Load<MyObject>(id); 
obj.Title = "Some Title"; 
_nhibernateSession.Transaction.Commit(); 

var obj = someObjectInMemoryNotInSession as MyObject; 
obj.Title = "Some Title"; 
_nhibernateSession.Update(obj); 
_nhibernateSession.Transaction.Commit(); 

你有沒有注意到的區別是:在第一種情況下並不需要更新,因爲OBJ是從會話中獲取的,會話將意識到其中的任何更改,但在第二個示例中,我們需要明確調用Update,因爲現在我們的obj已從會話中分離出來。

現在你的問題: 聲明:

if (((NHibernate.Impl.SessionImpl)session).IsSaved(obj) 
    session.Lock(obj, LockMode.None) 

在NH1.2效果很好,因爲這樣你在第一種情況下(當實體從會話加載的情況下),但現在你是第二種方法:

if (obj != null) 
    session.Lock(obj, LockMode.None) 

它不會加載obj會話,這就是爲什麼NHibernate它觸發數據庫更新。

如果你想避免這種情況只是調用Get()如果前:

obj = session.Get(id, LockMode.None); 

或者乾脆:

obj = session.Get(id); 

都將爲你的情況做的工作。

+0

感謝您的信息。請在我的腦海裏幫助我澄清這一點。我理解你的前兩個例子,並理解更新告訴NH它應該跟蹤一個分離的對象(如果沒有錯誤的話)。在NH1.2 IsSaved if語句中,分離的對象將被保存= true,因此執行Lock,就像obj!= null Lock語句一樣,因此執行相同的操作。還是我誤解? – TheITGuy

+0

更新將重新掛接對象,並且其延遲初始化的屬性可能會正常訪問,並且使用新會話懶加載數據 – diadiora

+0

如果實例存在,則指定鎖定模式,這不是您的情況,您只有在內存對象 – diadiora