ユーザーが渡す一連の日付に基づいて、イベント レコードをデータベースに「一括」挿入する必要があります。
私のイベント エンティティには、StartTime プロパティと StopTime プロパティがあります。Event エンティティは私のアプリケーションのコア エンティティであり、それに関連付けられた多数のコレクションとエンティティ参照があります。重い存在です。
したがって、私の元のコードでは、日付をループして次のようなことをしていました。
Session.Save(new Event {StartTime=startdate, StopTime=endDate});
しかし、これはうまくスケーリングできず、数百の日付を挿入するときにパフォーマンスを感じました。
そのため、すべての日付を一時テーブルに挿入することを考えましたが、HQL でそれを達成する方法がわかりませんでした。
そこで、次に考えたのは、すべての日付をサブクエリとして含めて、最も近いものにすることでした。そのアプローチは次のとおりです。
var hql = "INSERT INTO Event (Code, Comment, Description, Status, StartTime, StopTime)
SELECT ev.Code, ev.Comment, ev.Description, ev.Status, Dates.SDate, Dates.EDate
FROM Event ev,
(
SELECT '1/2/2012 3:00:00 PM' as SDate, '1/2/2012 6:00:00 PM' as EDate
UNION ALL SELECT '1/3/2012 3:00:00 PM', '1/3/2012 6:00:00 PM'
UNION ALL SELECT '1/4/2012 3:00:00 PM', '1/4/2012 6:00:00 PM'
) as Dates
WHERE ev.Id = :sourceEventId";
Session.CreateQuery(hql).SetInt32("sourceEventId", @event.Id).ExecuteUpdate();
しかし、hql は非常にあいまいなエラー コードで失敗します。私のオンライン調査によると、hql はまだ UNION 句をサポートしていません。
現在、このアプローチを SQL として書き直し、Session.CreateSQLQuery() を介して実行すると、うまく機能します。しかし、SQLとして実行したくありません。とにかく、それはNHibernateを使用する目的に反します。
HQL (または他の NHibernate テクノロジ) を使用してこれにアプローチできる別の方法はありますか?
ここで何か助けていただければ幸いです。
アップデート
これは従来の SQL Server データベースであり (sqlite で単体テストを実行しています)、すべてのエンティティが SQL の Identity 列を使用して ID を生成していることを忘れていました。そのため、バッチの試行はすべて失敗します。
以下のコメントで説明したように、ステートレス セッション アプローチも試しました。NHibernate は、遅延ロードされたすべてのエンティティを最初に保存する必要があることを教えてくれませんでした。これらのマッピングを削除することで一時的にその問題を回避しましたが、それは機能し、通常のセッションよりも高速でした. それでも、すべてのエンティティを一度に 1 つずつ挿入する必要がありました。