Question

La relation entre plusieurs objets Produit et Fournisseur est multiple. Je dois pouvoir supprimer Fournisseur sans supprimer les Produits qui lui appartiennent.

Voici une version simplifiée des classes:

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; }
}

J'utilise FluentNHibernate, mais voici les mappages qu'il produit:

<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" />

Ceci crée une clé étrangère sur la table Products. Ainsi, lorsque je tente d'effectuer une suppression directe sur un fournisseur, une erreur de contrainte de clé étrangère se produit. J'ai essayé de changer la cascade en "tout", dans l'espoir de ne supprimer que la relation, mais en supprimant tous les produits et leurs autres objets associés.

Pour l'instant, la seule façon de résoudre ce problème consiste à itérer la collection Products du fournisseur et à définir la propriété Supplier sur null. Existe-t-il un moyen d’obtenir ce comportement grâce au mappage?

Était-ce utile?

La solution

Les propriétés de mappage ne prennent effet que lorsque l'entité est réellement chargée et lorsque vous n'interrogez pas via HQL. Par exemple, si vous spécifiez Cascade = ALL , si vous supprimez un fournisseur avec la requête " delete from Supplier où id =: id , vous obtiendrez probablement le même échec de contrainte FK, car hql ne déclenche pas de cascades (programmatiques).

Il semble que les produits soient le côté propriétaire de la relation, ce qui est bien. Je pense que vous avez deux choix:

  • Codez une méthode sur le fournisseur pour parcourir tous les produits et définissez le fournisseur du produit sur null, et utilisez cette méthode avant de supprimer un fournisseur
  • Avant d'émettre une suppression de fournisseur, assurez-vous que votre DAO définit le fournisseur du produit sur null

Exemple:

public int Delete(Supplier s) {
    return Session.CreateQuery("udpate Product set Supplier = null where Supplier = :supplier")
        .SetParameter("supplier", s)
        .ExecuteUpdate();
}

Autres conseils

NE PAS FAIRE CELA.

Votre modèle contient une affirmation implicite ou explicite selon laquelle tous les produits ont un fournisseur. La clé étrangère est là pour appliquer cette condition. La suppression du fournisseur tout en conservant les produits constitue une violation de votre modèle et entraînera probablement l'échec d'une grande partie de votre code, qui repose sur le fait que cela est toujours vrai.

Vous avez déjà découvert une chose que vous pouvez faire: pour chaque produit qui a ce fournisseur, vous pouvez définir la valeur null du fournisseur du produit. Cela ne violera pas votre condition, mais cela revient à dire "nous ne savons pas qui est le fournisseur de ce produit". et peut provoquer des échecs de code.

Pourquoi voulez-vous faire cela?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top