2

こんにちは、1 対多の ComplianceSet -> ComplianceItem があります。ComplianceItem には、1 対多の ComplianceItem -> ComplianceItemInstance があります。

私は持っている

コンプライアンス セット

HasMany(x => x.GetUserComplianceItems()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();

コンプライアンス項目

HasMany(x => x.GetUserComplianceItemInstances()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();

それから私のコードでは

userComplianceSet.GetUserComplianceItems().FirstOrDefault(....); ... userComplianceItem.RemoveUserComplianceItemInstance(userComplianceItemInstance);

このコードは戻ります

削除されたオブジェクトはカスケードによって再保存されます (関連付けから削除されたオブジェクトを削除します)[DecisionCritical.Core.Domain.UserComplianceSet#12]

今、これは非常にイライラしています。両方のコレクションからカスケードを削除すると、コードは成功を返しますが、データベースは何もしなかったことを示しています。ComplianceItemInstance.ComplianceItemId フィールドはまだ入力されており、もちろん項目はまだそこにあります。いずれにせよ、コレクションから子を削除し、コレクションを保持しているオブジェクトで save を呼び出して、おかしなことをやめさせたいだけです。カスケードのあらゆる種類の順列、保存 (セットの保存、アイテムの保存)、ComplianceItemInstance への削除の追加を試しましたが、これを機能させることができません。

助けてください

4

1 に答える 1

1

私は同じことに苦労してきました。反応は少し遅いですが、将来の読者が恩恵を受けるかもしれません.

子テーブルの外部キーとして null を許可する解決策は機能しますが、親なしでは子が存在できない場合、データベース設計の観点からは望ましくない可能性があります。NHibernate が必要とするという理由だけでデータベースの設計を変更することは、私が好むものではありません。また、双方向から単方向への変更は、私にとって望ましくありませんでした。そこで私は飛び込んで、あらゆる種類のマッピングの組み合わせを試しました。

私が見つけたのは、 inverse = true を使用すると問題が解決したことです。まず、これは NHibernate の悪い動作だと思いました。inverse = true は、ほとんどの場合、子コレクションが関係を担当するものとして説明されているためです。これについては、子と親の両方を手動で更新することで既に説明したと思います。しかし、この責任は何よりもデータベースに関するものです。

inverse = true を使用すると、マッピングの親側に Cascade.AllDeleteOrphan がある限り、親から子を削除することで子を削除できます。すべてが正しく更新されます。Cascade.All の使用を選択した場合は、子も明示的に削除する必要があります。

親がロードされていない場合は、現在のセッションで子を削除するだけで、すぐに子を削除することもできます。ただし、親がロードされている場合、これは機能しません。その場合、カスケードの再保存の問題が発生します。

私にとっての結論は、逆の作品です。また、inverse = false でより良い結果が得られるシナリオはまだ見つかっていませんが、NHibernate を深く掘り下げると、その意見に戻るかもしれません。

于 2012-04-03T13:23:59.737 に答える