2

http://fabiomaulo.blogspot.com/2008/12/identity-never-ending-storyで説明されているように、トランザクションが実際にコミットされる前に挿入が必要なため、ID ジェネレーターが作業単位を壊すことを理解し、受け入れます。 html . 私は、代替案と、それらがより優れている理由を認識しています(目前の問題と一般的に関連して)。

私が持っている質問は、実装がそのまま存在する理由と、これらの問題が EF に影響を与えるかどうかです (純粋な好奇心)。私が見た唯一の本当の正当化 i: 「セッション内のすべてのエンティティ (「永続エンティティ」と呼ばれる) を識別する必要があるため、NHibernate には ID が必要です。通常、ID は、レコードがデータベースに既に存在するかどうかを判断するためにも使用されます。 (保存されていない値)。」

しかし、なぜすぐに値を持たなければならないのでしょうか? コミットが発生するまで INSERT を延期できないのはなぜですか?

あまり重要でない質問: EF は同じ問題に悩まされていますか? ISession が適切な UoW 実装であることは知っています。EF は UoW パターンを実装していませんか、それともこの問題を処理する別の方法がありますか? もしそうなら、それは何ですか?

4

1 に答える 1

3

NHibernateで挿入が延期されない理由を正確に説明することはしませんが、NHibernateをセッションに配置すると、すぐに実際のエンティティIDが必要になると思います。

EFはこのアプローチを使用しませんが、EFアプローチが優れているという意味ではありません。まず第一に、EFにはIDジェネレーターのサポートが組み込まれていません。独自に実装することもできますが、NHが回避しようとしている問題のために、少し難しい場合があります。

ORMツールはIDマップを実装し、各エンティティを一意に識別する必要があります。NHはおそらくすぐに実際のIDを使用しますが、EFはID定義を延期し、一時キーを使用できます。この一時キーは、実際のIDがデータベースで定義されている場合に使用されます。つまり、MSSQLServerのIDENTITY列を意味します。EFは、データベースにレコードを挿入してクエリを実行した後でのみ、実際のIDを認識しますSCOPE_IDENTIY()。EFは実際のキーを受信すると、エンティティとそのすべての関係(FK)を更新して、実際のIDを反映します。

これは、このアプローチの最大の欠点でもあります。EFは、主キー値を取得するために、データベースへの個別のラウンドトリップですべてのレコードを挿入する必要があります(EFはコマンドバッチ処理をサポートしていません)。ここでは、ジェネレーターを使用してIDを事前生成し、それらのDMLコマンドをデータベースへの単一のラウンドトリップにバッチ処理できるNHとの最大の違いを見つけます。

EFで一時キーを使用すると、EF4.0で導入されたFKプロパティの使用を開始するときに別の副作用が発生します。FKプロパティを使用したら、PKを一意の一時値に明示的に設定する必要があります。そうしないと、リレーションを持つ2つのレコードの挿入が例外として失敗します(デフォルトのキー値を持つ2つのエンティティがあり、FKプロパティはどちらが正しいプリンシパルであるかを定義できません) )。

EFはデータベースで生成されたキーを処理するように設計されていますが、NHはアプリケーションで生成されたキーを優先します。

于 2012-07-10T13:25:41.003 に答える