2011-08-10 2 views
2

子エンティティへの初期化されていない参照を持つ切断されたエンティティを更新しようとしているコードのトラブルシューティングを行っています。その目的は、子をロードせずにParentのプロパティのみを更新することです。NHibernate 1対多 - なぜそれはnullの外部キーで子を更新していますか?

HasMany(x => x.ChildEntities) 
    .KeyColumn("ChildEntityId") 
    .Table("ChildEntity") 
    .Not.LazyLoad() 
    .Inverse() 
    .Cascade.All().AsBag(); 

Session.Update(親)が呼び出されると、2つの更新文が実行されます。最初は親オブジェクトを期待通りに更新します。

update Parent set ... where ParentId = 12345 

2回目の更新は私を混乱させる...

update ChildEntity set ParentId = null where ParentId = 12345 

はなぜNHibernateのは、第2のSQL文を発行していますか?私はChildEntitiesが初期化されておらず、NHibernateがおそらくParentの状態を強制しようとしていることを認識していますが、この2回目の更新をしないようにマッピングを微調整することはできません。私はマージ、レイジーローディング、さまざまなカスケードオプションなどを成功させずに試みました。コミットしようとするセッション内の唯一の接続エンティティはParentです。

私は通常、遅延読み込みを有効にしてエンティティを取得し、NHibernateをデータベースに持続させる前に、切断されたオブジェクト(DTOまたはエンティティ)から接続されたエンティティにマッピングすることでアプローチします。私は代替アプローチを提案する前に、上記がうまくいかない理由を理解したい。

答えて

4

これは迷惑でした。

!isInverse(AbstractCollectionPersister.cs)の場合にのみ実行できるブロックで、NHibernateソースから「コレクションを削除できませんでした」というクイック検索がブロックに表示されました。マッピングコードが明示的にそのコレクションにInverseを設定していたので、それは私の注意を引いた。

逆が偽であり、コレクションが空の場合、NHは、外部キーが親IDと等しい場合に外部キーをNULLに設定する子テーブルの更新を実行します。

Fluentは、指定された名前空間のすべてのエンティティを自動マップするように設定されています。手動マッピングを持つものは、自動マッピングによって無視されるという前提がありました。 Fluentが作成したhbm.xmlファイルを素早くチェックして、Inverseが設定されていないことを確認しました。明示的にオートマッピングから除外されたエンティティのリストにParentを追加し、すべてが機能し始めました。

.IgnoreBase<Parent>() 
関連する問題