2011-06-05 50 views
1

我有ninject在httpRequest上創建一個新會話,並在httpRequest結束時關閉它。如何修改我不想在nhibernate中提交的對象?

現在我通過nhibernate配置文件瞭解到,即使是查詢(讀取),我也應該始終將所有內容都包含在事務中。

這在我的代碼中造成了很多錯誤,因爲我會從數據庫中檢索一個對象,然後對該對象進行修改(主要是將utc時間轉換爲本地時間)。

這些修改應永遠被提交到數據庫,但因爲我現在包裹我所有的讀取查詢在交易中有什麼需要我去提交,並搶別的東西從數據庫中它並提交,它看到的我的對象發生了變化,並保存了應該將從未將保存到數據庫的更改。

我會使用evict,但後來我失去了延遲加載,並且通常會在實際執行一些其他激活延遲加載的查詢之前轉換時間。

我該怎麼辦?

回答

2

NHibernate 3.1在IQueryICriteria上有一個SetReadOnly()方法,確保查詢返回的對象不會被會話持久化。

+0

@Dmitry - 你有鏈接。我通常將我的東西轉換爲List() – chobo2 2011-06-05 04:58:33

+0

我不確定是否有最新版本的NH的任何文檔。你會做一些像「criteria.SetReadOnly(true).List()」。這是一個鏈接到Jira的功能:http://216.121.112.228/browse/NH-908 – 2011-06-05 05:02:32

+0

@Dmitry - 這似乎是放在我的流利映射屬性。這不會工作,因爲有時我需要更新該列。 – chobo2 2011-06-05 05:02:56

2

我建議您將查詢結果加載到viewmodel,然後在您的viewmodel的屬性中將您的日期轉換爲本地時間。因爲連接到nHibernate會話的viewmodelNOT,所以當您的httpRequest結束提交事務時,您不會更新實體。

一個viewmodel實際上是一個DTO,可以描述爲您的數據flattened model

請參閱本post更多的信息(尤其是回答關於automapper)

編輯看來,你的痛點是當數據的實際顯示被執行時。當我遇到這些問題時,我總是使用displayFor模板。在我看來,我用沿則路線的東西: -

請注意,這是一個人爲的例子: -

<h1>Books</h1> 
<ul> 
@foreach (var book in Model) 
{ 
    <li>@book.Name @Html.DisplayFor(x=> book.UnitPrice, "Price")</li> 
} 
</ul> 

,然後創建一個顯示模板/Views/Shared/DisplayTemplates/Price.cshtml

@model decimal 
<span>&pound;@Model</span> 

注:該視圖可以通過幫手等執行您的計算...

這給你很多好處,但它確實意味着我使用價格,我必須使用一個顯示器y模板。不過,我覺得記住我需要爲我的所有價格,日期等使用顯示模板,而不是一些可能會錯過的名稱助手。它始終是關於訓練/調節自己。

它的一切開放辯論,並在一天結束時,你需要感覺舒適的工作方式。但顯示模板似乎對我更好。

我還應該指出,我強烈建議您將此視爲顯示問題,而不是試圖提供從數據庫中檢索數據的kludge。

+0

是的,我已經使用視圖模型和自動映射器。爲什麼我決定在結果上做這件事的一個原因是,原因很簡單,在過去的版本中,很多時候轉換被遺忘或被用於多次給出錯誤的結果。所以我想,一旦你得到的對象將其轉換爲當地時間,並忘記必須轉換它。第二件事是在這種情況下不能使用automapper,因爲我需要傳遞用戶時區設置,並且automapper無法在時區設置中傳遞。 – chobo2 2011-06-05 06:42:36

+0

好的,這是asp.net mvc應用程序嗎?也是第3版? – Rippo 2011-06-05 06:48:56

+0

是mvc 3.0。你的模板方式可能會工作,但我jsut不喜歡模板,因爲他們給我的意見更少的靈活性,因爲你不能像HTML屬性和類似的東西通過displayTemplate html helper傳遞。 – chobo2 2011-06-06 03:24:00