我們使用某種標準語言將查詢的where子句從客戶端傳遞到服務器。當涉及到服務器時,我們將它轉換爲linq表達式並使用NH執行查詢。 例如「獲得活動頁面」查詢好像是:如何通過linq表達式作爲where子句執行多行更新
Session.Query<EventExtractData>()
.Where(message.Criteria.GetExpression())
.OrderByDescending(e => e.CreateTimeUtc)
.Skip(message.Start)
.Take(message.Size)
.ToArray()
message.Criteria是實現抽象的標準< T>「原子」準則的組成並擁有和<牛逼粘>和Or < T>準則。每個具體標準實現表達式< Func < T,bool >> GetExpression()函數。
這是工作。
現在我們想要使用相同的標準在多行上執行更新。
我不能只取符合條件的所有行,然後逐個更新它們。這將是一個性能問題。
我想通過一個命令來執行更新:
UPDATE <real view name of mapped EventExtractData class>
SET <my business logic>
WHERE <my criterions' linq expression translated to SQL where clause>
我正在尋找一種方式來實現與NH此更新。
Actualy,我認爲我需要的是用NH linq提供程序將linq表達式解析爲sql。
如何做到這一點?
---------------------------------- Update ----------- ---------------
有鑽入NH內部的一些intermideate結果:
var implementor = session.GetSessionImplementation();
var hqlUpdate = "update EventExtractData e set e.Status = 2, e.CloseReason = 'Multiple close', e.ClosedUTC = :now";
var updatePlan = new HQLStringQueryPlan(hqlUpdate, false, implementor.EnabledFilters, implementor.Factory);
string sqlUpdate = updatePlan.SqlStrings[0];
,這給了我下面的SQL表達式:
更新EV_EventData_VW設置狀態= 2,CloseReason ='多次關閉', ClosedUTC =?
現在,我將模擬選擇查詢,並得到它的SQL表達式
var dummyQuery = session.Query<EventExtractData>().Where(message.Criteria.GetExpression());
var nhQuery = new NhLinqExpression(dummyQuery.Expression);
var selectPlan = new HQLExpressionQueryPlan(nhQuery.Key, nhQuery, false, implementor.EnabledFilters, implementor.Factory);
string sqlSelect = selectPlan.SqlStrings[0];
,這給了我:
選擇
eventextra0_.ID爲ID31_,
eventextra0_.NaturalID爲 NaturalID31_ ,
eventextra0_.Site as Site31_,
eventextra0_.CreateTimeUTC as CreateTi4_31_,
eventextra0_.Description如Descript5_31_,
eventextra0_.EventTypeDisplayName如EventTyp6_31_,
eventextra0_.Severity如Severity31_,
eventextra0_.Status如 Status31_,
eventextra0_.CreateUser如CreateUser31_,
eventextra0_.Owner如Owner31_,
eventextra0_。 CloseUser爲 CloseUser31_,
eventextra0_.ExceededUTC爲Exceede12_31_,
eventextra0_.ExpiredUTC爲ExpiredUTC31_,
eventextra0_.ClosedUTC爲ClosedUTC31_,
eventextra0_.OwnedUTC as OwnedUTC31_,
eventextra0_。IsFalseEvent爲IsFalse16_31_,
eventextra0_.CloseReason爲CloseRe17_31_,
eventextra0_.IsCloseCommentMandatory爲IsClose18_31_,
eventextra0_.PossibleTrueCloseReasons爲Possibl19_31_,
eventextra0_.PossibleFalseCloseReasons爲Possibl20_31_,
eventextra0_.IsExpired爲IsExpired31_,
eventextra0_.IsExceeded 爲IsExceeded31_,
eventextra0_.SourceElementID爲SourceE23_31_,
eventextra0_.SourceElementDisplayName作爲SourceE24_31_
從 EV_EventData_VW eventextra0_
eventextra0_.IsExpired = 1 and eventextra0_.ExpiredUTC <?
及其與的幾個milions錶行。在最糟糕的情況下,用戶需要更新所有行。所以我無法獲取事件的ID。是的,我們警告客戶有關問題,但他仍然希望通過選擇標準和單擊來更新多行。 –
@StanB在這種情況下,據我所知,你不能使用LINQ執行DML風格的操作。在工作中我有類似的情況,我很快 - 必須使用StringBuilder建立一個HQL查詢。 – rebelliard