2016-04-03 62 views
0

如果使用INSERT查詢添加對象的狀態是什麼?而我怎麼能得到這個對象相同的會話?使用本地SQL在NHibernate中對INSERT查詢使用CreateSQLQuery

session.CreateSQLQuery("INSERT INTO table (...) VALUES (...)").ExecuteUpdate()) 

我知道他的身份證,因此採用這種對於GET

插入對象:

sessison.Get<MyObjectType>(id) 

,但對象是空的,因爲會議是相同的,並承諾仍懸而未決。 我在做什麼錯?

P.S.使用CreateSQLQuery需要,因爲我的子對象foo基於他的父欄創建,但bar和foo具有相同的ID,並且使用了Table Per Concrete Class

+0

這對我來說不正常。在原始SQL級別,我們可以讀取任何隔離級別的未提交數據,只要我們正在讀取具有待處理數據的事務。檢查'ExecuteUpdate',它應該立即發送查詢到數據庫。你可以檢查你的情況與分析器?然後'Get'應該能夠找到你的新實體,除非你在某些特定情況下,比如在會話中有一個陳舊的實體具有相同的Id,但標記爲刪除。啓用NHibernate調試log4net日誌,並從'DefaultLoadEventListener'的日誌應該給你詳細信息。 –

+0

不,在ExecuteUpdate之後,分析器說,我',只是發送插入,但沒有提交。我認爲這取決於ISessionProvider生活方式 –

+0

只是發送插入是我期望在分析器中看到的。無論如何,你的評論[這裏](/ questions/36386613/using-creatingqlquery-with-insert-query-in-nhibernate?noredirect = 1#comment60434278_36388601)告訴你已經找到了一些東西,你應該添加它作爲你自己的答案問題,並接受它。或者,如果您不明白爲什麼您的更改會導致您的代碼正常工作,那麼也許您應該提出一個新問題。 –

回答

0

我找到了解決辦法。

在我的情況下,ISessionProvider有Life style - perWebRequest。這意味着會話在結束Web請求後被提交。

下一步。插入後,我們沒有實體,但我們可以將基於插入數據創建的新實體與當前會話合併。

session.Merge(new Entity(...)); 

,或者如果您在Persistence Context有母公司,你需要做:

session.Evict(parentEntity); 
session.Merge(new Entity(...)); 

Evict刪除實體與一些ID(小孩和父母有一定的ID),否則你會得到一個異常。 這會將實體與當前會話合併,並且在使用sessison.Get<MyObjectType>(entityId)時,對象不爲null。

0

要麼嘗試.Get之前提交第一個事務,要麼您可能能夠使用.Load,而不是在更新或插入之前只需將此實體與另一個實體相關聯。

由於您沒有處理實體,因此編寫原始sql查詢不會保存會話中的內容。

+0

我有點驚訝。如果我們在同一交易中閱讀,我們是不是應該能夠讀取當前掛起交易中添加的數據?通常我們不應該需要提交交易。 ExecuteUpdate實際上只在'Flush'上執行嗎? (如果這是已經加載的實體上的SQL更新情況,我們將需要從會話中驅逐實體。) –

+0

這取決於您在讀取數據時使用的事務隔離級別。您必須明確地將其設置爲讀取未提交的數據才能執行此操作,並且這是假定更新/插入實際上已發送到尚未處理的事務中的數據庫。 –

+0

你讓我懷疑,但在閱讀中測試承諾'begin tran;插入Parametre(Code)值('test');從參數中選擇*;回滾; select * from parametre;'在第二種情況下會減少一個結果,這意味着如果我們仍處於同一事務中,則不需要讀取未提交的用於讀取待處理數據的讀取。在插入案例中,我不明白爲什麼NHibernate的一級緩存可能會造成干擾。 –