0

ある種の基準言語を使用して、クライアントからサーバーにクエリのwhere句を渡します。サーバーに関しては、それをlinq式に変換し、NHを使用してクエリを実行します。たとえば、「イベントページを取得」クエリは次のようになります。

Session.Query<EventExtractData>()
.Where(message.Criteria.GetExpression())
.OrderByDescending(e => e.CreateTimeUtc)
.Skip(message.Start)
.Take(message.Size)
.ToArray()

message.Criteriaは、抽象的なCriterion <T>を実装し、And<T>およびOr<T>基準に接着された「アトミック」基準の組み合わせです。それぞれの具体的な基準は、Expression <Func <T、bool >> GetExpression()関数を実装します。
それは仕事です。
次に、同じ基準を使用して、複数の行で更新を実行します。
基準に準拠するすべての行をフェッチして、それらを1つずつ更新することはできません。パフォーマンスの問題になります。
1つのコマンドで更新を実行したい:

UPDATE <real view name of mapped EventExtractData class> 
SET <my business logic> 
WHERE <my criterions' linq expression translated to SQL where clause>

NHでこのアップデートを実装する方法を探しています。
実際、私が必要としているのは、NHlinqプロバイダーを使用して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 =?

次に、selectクエリをシミュレートし、その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を
Site31_として、
eventextra0_.CreateTimeUTCをCreateTi4_31_として、
eventextra0_.DescriptionをDescript5_31_として、
eventextra0_.EventTypeDisplayNameをEventTyp6_31_として、
eventextra0_.EventTypeDisplayNameをEventTyp6_31_として選択

ます。 .CreateUser as CreateUser31_、
eventextra0_.Owner as Owner31_、
eventextra0_.CloseUser as CloseUser31_、
eventextra0_.ExceededUTC as Exceede12_31_、
eventextra0_.ExpiredUTC as ExpiredUTC31_、
eventextra0_.ClosedUTC as ClosedUTC31_
OwnedUTC31_としてeventextra0_.OwnedUTC eventextra0_.IsFalseEvent
IsFalse16_31_として、 eventextra0_.CloseReason CloseRe17_31_として、 IsClose18_31_としてeventextra0_.IsCloseCommentMandatory、
Possibl19_31_ としてeventextra0_.PossibleTrueCloseReasons、 Possibl20_31_など eventextra0_.PossibleFalseCloseReasons IsExpired31_としてeventextra0_.IsExpired、 IsExceeded31_としてeventextra0_.IsExceeded eventextra0_。 SourceElementID as SourceE23_31_、 eventextra0_.SourceElementDisplayName as SourceE24_31_ from EV_EventData_VW eventextra0_ where eventextra0_.IsExpired = 1 and eventextra0_.ExpiredUTC <?









4

1 に答える 1

1

DML スタイルの操作を使用できますが、HQL に頼る必要があります。

ただし、LINQ でクエリを実行する必要がある場合は、対応する 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();
于 2012-05-06T14:55:21.817 に答える