1

Productオブジェクトと。の間には多対1の関係がありますSupplier。それに属するを削除Supplierせずに削除できる必要があります。Product

クラスの簡略化されたバージョンは次のとおりです。

public class Supplier {
    public virtual IList<Product> Products { get; protected set; }
}

public class Product {
    // Product belongs to a Category but Supplier is optional
    public virtual Supplier Supplier { get; set; }
    public virtual Category Category { get; set; }
}

FluentNHibernateを使用していますが、生成されるマッピングは次のとおりです。

<bag name="Products" cascade="save-update" inverse="true">
      <key column="SupplierID" />
      <one-to-many class="Me.Product, Me, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>

<many-to-one name="Supplier" column="SupplierID" />

これにより、Productsテーブルに外部キーが作成されるため、Supplierで直接削除を実行しようとすると、外部キー制約エラーが発生します。関係を削除するだけであると期待して、カスケードを「all」に変更しようとしましたが、すべての製品とそれに関連する他のオブジェクトが削除されました。

これを今すぐ解決するために私が見ることができる唯一の方法は、SupplierのProductsコレクションを繰り返し、Supplierプロパティをnullに設定することです。マッピングを通じてこの動作を実現する方法はありますか?

4

2 に答える 2

2

マッピングプロパティは、エンティティが実際に読み込まれている場合、およびHQLを介してクエリを実行していない場合にのみ有効になります。たとえば、を指定Cascade=ALLした場合、クエリを使用してサプライヤを削除すると"delete from Supplier where id=:id"、hqlは(プログラムによる)カスケードをトリガーしないため、おそらく同じFK制約の失敗が発生します。

製品は関係の所有側であるように思われ、それは良いことです。私はあなたが2つの選択肢があると思います:

  • サプライヤにいくつかのメソッドをコーディングして、すべての製品を反復処理し、製品のサプライヤをnullに設定し、サプライヤを削除する前にこのメソッドを使用します
  • サプライヤー削除を発行する前に、DAOが製品のサプライヤーをnullに設定していることを確認してください

例:

public int Delete(Supplier s) {
    return Session.CreateQuery("udpate Product set Supplier = null where Supplier = :supplier")
        .SetParameter("supplier", s)
        .ExecuteUpdate();
}
于 2009-04-29T10:44:24.650 に答える
0

これをしないでください。

モデルには、すべての製品にサプライヤーがあるという暗黙的または明示的なアサーションがあります。外部キーは、この条件を強制するためにあります。製品を保持したままサプライヤーを削除すると、モデルに違反し、これに依存するコードの多くが失敗する可能性があります。

あなたができることの1つは、すでに発見したことです。このサプライヤを持つすべての製品について、製品のサプライヤをnullに設定できます。これはあなたの条件に違反することはありませんが、「この製品のサプライヤーが誰であるかわからない」と言うのと同じであり、コードの失敗を引き起こす可能性があります。

なぜあなたはこれをしたいのですか?

于 2009-04-29T11:16:47.180 に答える