2009-08-07 44 views
24

我正在使用NHibernate的項目。 我不會保持會話打開。當我需要獲取或保存對象時,我打開會話,執行我所需的操作,然後關閉會話。所以我一直在處理與session分離的對象。什麼是當會話分離時只更新NHibernate中更改的屬性的最佳方法?

例如,當我需要從數據庫中獲取對象時,我打開會話,然後調用session.Get()並關閉會話。然後我更新分離對象的一些屬性。當我需要保存對數據庫的更改時,我調用打開會話的方法,調用session.Update(myObject)並關閉會話。

但是,當我這樣做,NHibernate生成的SQL更新我已映射的所有字段,即使他們沒有改變。我的建議是當對象脫離會話時,NHibernate無法跟蹤已做出的更改。 當您只想更新從會話中分離的對象時,您使用什麼方法?如何跟蹤分離對象的更改?

感謝

回答

17

的問題是:你想這樣做,爲什麼呢?如果你只更新已更改的列,我認爲這不是一個優化。

你在數據庫中有觸發器嗎?

如果是這樣,你可以做到以下幾點:在映射

  • 使用select-before-update="true"dynamic-update="true"。這使NH在更新之前執行查詢,並且只在更改時更新,並且只更改已更改的列。我不確定它是否爲每次更新選擇,或只有當它不在會話中。
  • 使用Merge而不是更新。這實際上是相同的:只有在數據庫中尚未存在的情況下,它才從數據庫中選擇實體。還可以使用dynamic-update="true"。還有一個權衡:Merge返回連接的實例,如果在會話中已經有一個。所以你應該拋棄你傳入的實例,並使用從Merge開始的實例。

其實我不會在乎更新的列。它可能更快地盲目更新而不是執行前面的查詢。

+0

我在數據庫中沒有任何觸發器。那麼,我想這樣做,只是因爲我用來更新只有屬性已被更改。你的意思是盲目更新對象可能會更快,並且Merge需要一些額外資源? – 2009-08-07 09:41:25

+0

順便說一句,爲什麼我應該使用select-before-update =「true」,如果它沒有它的工作? – 2009-08-07 11:18:31

+0

合併需要額外的查詢,這是一個額外的數據庫往返並有其開銷。我認爲select-before-update只是爲了避免合併。合併對商業邏輯有影響。 – 2009-08-07 11:50:17

6

使用動態更新的mapping = 「真」。
此外,更新分離對象使用這樣的:

Session.SaveOrUpdateCopy(myObject) 
+0

我想接受這個答案,只想問你一件事:SaveOrUpdateCopy和Merge有什麼區別?我可以使用合併分離對象或SaveOrUpdateCopy是一個更好的方法? – 2009-08-07 08:31:01

+0

動態更新只適用於連接的實體。 NH如何確定哪些屬性在會話中沒有舊狀態時發生了變化? – 2009-08-07 08:59:36

+0

我不是爲什麼,但當我設置動態更新屬性,並說SaveOrUpdateCopy或合併它只保存我的對象更改列。當我刪除動態更新屬性,NHibernate再次保存所有的屬性,即使我只改變了一個!但它是如何工作的是一個問題... – 2009-08-07 09:09:34

相關問題