我们使用某种标准语言将查询的where子句从客户端传递给服务器。当涉及到服务器时,我们将其转换为linq表达式并使用NH执行查询。 例如,“获取事件页面”查询似乎是:
Session.Query<EventExtractData>()
.Where(message.Criteria.GetExpression())
.OrderByDescending(e => e.CreateTimeUtc)
.Skip(message.Start)
.Take(message.Size)
.ToArray()
message.Criteria是实现抽象Criterion&lt; T&gt;的“原子”标准的组合。用&lt; T&gt;粘合。和或者&lt; T&gt;准则。每个具体标准实现表达式&lt; Func&lt; T,bool&gt;&gt; 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 怎么做?
----------------------------------更新------------ --------------
在NH内部钻孔有一些中间结果:
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设置Status = 2,CloseReason ='Multiple close', 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 as NaturalID31_,
eventextra0_.Site as Site31_,
eventextra0_.CreateTimeUTC as CreateTi4_31_,
eventextra0_。描述为Descript5_31_,
eventextra0_.EventTypeDisplayName as EventTyp6_31_,
eventextra0_.Severity as Severity31_,
eventextra0_.Status as Status31_,
eventextra0_ .CreateUser as CreateUser31 _,
eventextra0_.Owner as Owner31_,
eventextra0_.CloseUser as CloseUser31_,
eventextra0_ .ExceededUTC as Exceede12_31_,
eventextra0_.ExpiredUTC as ExpiredUTC31_,
eventextra0_.ClosedUTC as ClosedUTC31_,
eventextra0_.OwnedUTC 作为OwnedUTC31_,
eventextra0_.IsFalseEvent为IsFalse16_31_,
eventextra0_.CloseReason为CloseRe17_31_,
eventextra0_.IsCloseCommentMandatory as IsClose18_31_,
eventextra0_.PossibleTrueCloseReasons为Possibl19_31_,
eventextra0_.PossibleFalseCloseReasons为Possibl20_31_,
eventextra0_.IsExpired as IsExpired31_,
eventextra0_.IsExceeded as IsExceeded31_,
eventextra0_.SourceElementID as SourceE23_31_,
eventextra0_.SourceElementDisplayName作为SourceE24_31_
来自 EV_EventData_VW eventextra0_
其中eventextra0_.IsExpired = 1和 eventextra0_.ExpiredUTC&LT ;?
答案 0 :(得分:1)
您可以使用DML样式操作,但必须resort to HQL。
但是,如果您觉得需要使用LINQ进行查询,我会获取相应的ID,这些ID应该是一个非常轻量级的查询,然后使用HQL:
var ids = Session.Query<EventExtractData>()
.Where(message.Criteria.GetExpression())
.Select(x=>x.Id)
.ToList();
int count = Session.CreateQuery(@"update EventExtractData evt
set evt.Date =:date
where evt.Id in (:ids)")
.SetParameter("date", DateTime.Now)
.SetParameterList("ids", ids)
.ExecuteUpdate();