2009-08-24 1 views

答えて

27

遅延読み込みを使用している場合は、読み込み時にのみプロキシが作成されます。

NH 2.1では、HQLを使用できます。それが実際にどのように見えるかを確認しますが、このようなものではない:これはSQLインジェクションの対象となることをノート - 使用可能性がsetParameterを(と代わりにクエリをパラメータ化場合)

session.Delete(string.Format("from {0} where id = {1}", type, id)); 

編集:

ロードでは、Id列の名前を知る必要はありません。あなたはそれを知る必要がある場合

、あなたはそれはNHのメタデータによって取得することができます:

sessionFactory.GetClassMetadata(type).IdentifierPropertyName 

別の編集を。

session.Delete()

エンティティ

session.Delete()を使用してインスタンス化され、NHとにかくエンティティをロードします。最初は私はそれが気に入らなかった。そして私はその利点を実感しました。エンティティが継承、コレクション、または「任意の」参照を使用する複雑な構造の一部である場合、実際にはより効率的です。例えば

クラスAB両方がBaseから継承した場合、それは実際のエンティティはタイプAである場合テーブルB内のデータを削除しようとしません。実際のオブジェクトを読み込まなければこれはできません。これは、継承された型が多くあり、それぞれに多くのテーブルが追加されている場合に特に重要です。

Baseのコレクションがある場合は、同じ状況が発生します。すべてのインスタンスはAです。コレクションをメモリにロードするとき、NHはB -stuffを削除する必要がないことを知っています。エンティティAC S(など)が含まれB Sのコレクションを持っている場合

は、それがBのコレクションが空の時に任意のC秒を削除しようとしません。これは、コレクションを読むときにのみ可能です。これは、Cがそれ自身の複合体であり、さらに多くのテーブルを集める場合などに特に重要です。

構造が複雑で動的であるほど、実際のデータを「盲目的に」削除するのではなく、実際のデータを読み込む方が効率的です。

HQLは、HQLは、メモリにデータをロードしないように削除します

落とし穴を持って削除します。しかし、HQL削除はそれほど賢明ではありません。基本的にエンティティ名を対応するテーブル名に変換し、データベースから削除します。さらに、集計された収集データを削除します。

単純な構造では、これはうまく効率的に動作する可能性があります。複雑な構造では、すべてが削除されるわけではなく、制約違反や「データベースメモリリーク」が発生します。

結論

IはまたNHで削除を最適化しようとしました。ほとんどの場合、NHはまだ賢く、「うまくいく」ため、通常は十分に速いので、私は諦めました。私が書いたもっとも複雑な削除アルゴリズムの1つは、NHマッピング定義を解析し、そこから削除文を作成することです。そして、驚きはありません。削除する前にデータベースからデータを読み取らなければ、不可能です。 (私はちょうど主キーをロードするためにそれを減らしました)。

+0

私はIdカラムの名前を知っていると仮定しているので、このコードをそのまま使うことはできません。 ID列の名前を見つけるために、実際のエンティティのCLR型を指定することは可能ですか?結局それは写像にあります。その後、Id列の名前を取得した後、HQLを実行することができました。ありがとう – mark

+1

私の追加の注意を参照してください。 –

+0

ほぼありますが、まだ問題はあります。いくつかのエンティティは、そのマッピングにentity-nameを定義しますが、すべてではありません。エンティティタイプは常に知られています。問題は、マッピングでentity-nameを定義しているエンティティの型が指定されている場合、GetClassMetadataがnullを返すことです。したがって、sessionFactory.GetClassMetadata(type)を呼び出すとnullになります。どうしようかな?ありがとう。 – mark

関連する問題