私は以下の作業を行います:すべてのアクティブなアカウントの利子を計算します。過去に私はAdo.Netとストアドプロシージャを使ってこのようなことをしていました。 今度は、純粋なPOCOで複雑なアルゴリズムを簡単に実行できるように見えるので、NHibernateでこれをやろうとしました。 次のようにしたい(擬似コード): foreach account in accounts calculate interest save account with new interest
NHibernateは大量のデータを処理するようには設計されていません。私にとっては、一度にすべてのアカウントをメモリに入れなくても、このようなループを構成することができれば十分です。 メモリの使用量を最小限に抑えるために、私はの代わりにIStatelessSession
を外部ループに使用します。 私はAyendeが提案したアプローチを試みました。 2つの問題があります。NHibernateで大きな結果セットを処理する
- CreateQueryは "magic strings"を使用しています。
- より重要:説明どおりに動作しません。
私のプログラムは動作しますが、ODBCトレースをオンにした後、私はすべてのフェッチが初めて実行された.List
にラムダ式の前に行われたデバッガで見ました。 私は自分自身が別の解決策を見つけました:session.Query
foreachで使った.AsEnumerable()
を返します。再び二つの問題:
- 私はまだ(すべては最初の利息計算の前にフェッチ)説明したように動作しないのIQueryable
- 上IQueryOverを好むだろう。
IQueryOver
にはAsEnumerable
が含まれていない理由がわかりません。また、引数を持つList
メソッド(CreateQuery
など)もありません。私は再び.Future
を試みたが、しました:未来の
- ドキュメントは、私は(すべてが最初の利息計算の前にフェッチ)必要があるとして、まだ動作しませんストリーミング機能
- を説明していません。
要約:NHibernateには、Ado.NetのdataReader.Read()
に相当するものがありますか?
NHibernateの純粋なアプローチの代わりに、dataReader.Read()
を使用するメインループと、Ado.NetループのIDを持つLoad
アカウントを使用します。ただし、キーを使用して各アカウントを読み取ることは、外部ループで行われるフェッチのシーケンスよりも遅いです。
NHibernateバージョン4.0.0.4000を使用しています。
すべての更新を1回のトランザクションで行うことはできますが、最初にすべてのアカウントを取得してから変更を加え、1回のバッチコールでemを保存する必要があります。私は前に同様の問題に対処しようとしましたが、私の最大の問題は通常、SQLプロファイラを使用すると見つけやすいselect-n問題を扱っていました –
データベーストランザクションは私にとって問題ではありません。すべてのアカウントまたは各アカウントごとに1つのトランザクションにすることができます。私の心配はメモリ消費に関係しています。私は生産システム(約1 mlnのアカウント)ですべてのアカウントをすぐにメモリに取り込むことができるかどうかはわかりません。 – robsosno
また、Jaguarによれば、メモリ内のオブジェクトの数があるしきい値を超えたときにパフォーマンスが低下します。 – robsosno