Contrainte de clé étrangère peut causer des cycles ou plusieurs cascade chemins?
J'ai un problème lorsque j'essaie d'ajouter des contraintes à mes tables. J'obtiens l'erreur:
L'introduction de la contrainte de CLÉ ÉTRANGÈRE 'FK74988DB24B3C886" sur la table "Employés" peut provoquer de cycles ou en cascade de plusieurs chemins. Spécifier on DELETE NO ACTION ou de la mise À JOUR, AUCUNE ACTION, ou modifier d'autres contraintes de CLÉS ÉTRANGÈRES.
Ma contrainte est entre un Code
table et un employee
table. Le Code
table contient Id
, Name
, FriendlyName
, Type
et un Value
. Le employee
a un certain nombre de champs que les codes de référence, de sorte qu'il peut être une référence pour chaque type de code.
J'ai besoin que les champs soit défini comme null si le code est référencé est supprimé.
Des idées comment je peux faire cela?
- L'une des solution est ici
Vous devez vous connecter pour publier un commentaire.
SQL Server n'est qu'un simple comptage de la cascade des chemins et, plutôt que d'essayer de déterminer si les cycles existent réellement, il suppose le pire et refuse de créer le référentiel des actions (en CASCADE): vous pouvez et devez toujours créer les contraintes sans les actions d'intégrité référentielle. Si vous ne pouvez pas modifier votre conception (ou cela pourrait compromettre les choses), alors vous devriez envisager d'utiliser des déclencheurs comme un dernier recours.
FWIW résoudre cascade de chemins est un problème complexe. D'autres produits SQL va simplement ignorer le problème et vous permettent de créer des cycles, auquel cas ce sera une course pour voir qui va remplacer la valeur du dernier, probablement à cause de l'ignorance de la créatrice (p. ex. ACE/Jet n'est présent). Je comprends certains produits SQL va tenter de résoudre les cas les plus simples. Reste que, SQL Server n'essayez même pas, il joue ultra sécuritaire en interdisant l'accès de plus d'un chemin et au moins il vous dise de le faire.
Microsoft eux-mêmes conseille l'utilisation de déclencheurs à la place de contraintes FK.
Une situation typique avec de multiples cascasing chemins de ceci:
Une table de maître avec deux détails, disons-le, "Master" et "Detail1" et "Detail2". Deux détails sont à supprimer en cascade. Jusqu'ici pas de problèmes. Mais que faire si les détails ont un un-à-plusieurs-relation avec un autre tableau (dire "SomeOtherTable"). SomeOtherTable a un Detail1ID-colonne ET un Detail2ID-colonne.
En d'autres termes: une partie des enregistrements dans SomeOtherTable sont liés avec Detail1-dossiers et que certains enregistrements dans SomeOtherTable sont liés avec Detail2 enregistrements. Même si il est garanti que SomeOtherTable-enregistrements de ne jamais appartenir à deux Détails, il est maintenant impossible de faire SomeOhterTable dossiers de l'effacer en cascade pour les détails, parce qu'il y a de multiples en cascade des chemins de Maître à SomeOtherTable (une via Detail1 et via Detail2).
Maintenant, vous pouvez déjà avoir compris cela. Voici une solution possible:
Tous les champs ID sont la clé des champs et de l'auto-incrémentation. Le point crucial réside dans la DetailMainId champs des tableaux détaillés. Ces champs sont à la fois importants et référentiel de contrainte. Il est maintenant possible de supprimer en cascade tout en ne supprimant maître-dossiers. L'inconvénient est que pour chaque detail1-enregistrement ET pour chaque detail2, il doit également être un DetailMain-enregistrement (qui est en fait créé d'abord pour obtenir la bonne et unique id).
Je tiens à souligner qu' (fonctionnellement) il y a une GRANDE différence entre les cycles et/ou plusieurs chemins d'accès dans le SCHÉMA et les DONNÉES. Alors que les cycles et peut-être multipaths dans les DONNÉES pourraient certainement compliqué de traitement et de provoquer des problèmes de performances (coût de la "correctement", manutention), le coût de ces caractéristiques dans le schéma doit être proche de zéro.
Depuis plus apparent des cycles de Rdb se produire dans des structures hiérarchiques (organigramme, partie, sous-partie, etc.) il est regrettable que SQL Server suppose le pire; c'est à dire, le schéma du cycle == cycle de collecte de données. En fait, si vous utilisez RI contraintes que vous ne pouvez pas construire un cycle dans les données!
Je soupçonne le multipath problème est similaire; c'est à dire, plusieurs chemins d'accès dans le schéma n'implique pas nécessairement de multiples chemins d'accès dans les données, mais j'ai moins d'expérience avec le multipath problème.
Bien sûr, si SQL Server ne permettent de cycles qu'il avait encore fait l'objet d'une profondeur de 32, mais c'est probablement suffisant pour la plupart des cas. (Dommage que ce n'est pas un paramètre de base de données, cependant!)
"Au lieu de Supprimer les" déclencheurs ne fonctionnent pas non plus. La deuxième fois qu'une table est visité, le déclencheur est ignoré. Donc, si vous voulez vraiment pour simuler une cascade, vous aurez à utiliser des procédures stockées dans la présence de cycles. Au Lieu de Supprimer un Déclencheur pourrait fonctionner pour les trajets multiples cas, cependant.
Celko suggère une "meilleure" manière de représenter des hiérarchies qui n'introduisent pas de cycles, mais il y a des différences.
Il y a un article qui explique comment effectuer la suppression multiple chemins à l'aide de déclencheurs. C'est peut-être utile pour des scénarios complexes.
http://www.mssqltips.com/sqlservertip/2733/solving-the-sql-server-multiple-cascade-path-issue-with-a-trigger/
Par les sons de celui-ci, vous avez un OnDelete/OnUpdate action sur l'un de vos Clés Étrangères, qui va modifier vos codes table.
Par la création de cette Clé Étrangère, vous auriez du créer un problème cyclique,
E. g. Mise à jour des Employés, des causes, des Codes de changé par une Action de mise à Jour, amène les Employés à être modifié par une Action de mise à Jour... etc...
Si vous publiez votre Table de Définitions pour les deux tableaux, & votre Clé Étrangère/les définitions de contraintes, nous devrions être en mesure de vous dire où est le problème...
C'est parce que Emplyee pourrait ont Collection d'une autre entité dire Qualifications et de Qualification peut avoir quelques autres de la collection des Universités
par exemple,
}
}
}
Sur DataContext il pourrait être comme ci-dessous
}
dans ce cas, il est de la chaîne de l'Employé de Qualification et De Qualification pour les Universités. Donc, il jetait même exception pour moi.
Il a travaillé pour moi quand j'ai changé de
À
Déclencheur est la solution pour ce problème:
C'est une erreur de base de données de type trigger politiques. Un déclencheur est code et pouvez ajouter quelques intelligences ou de conditions une Cascade de relation comme la Cascade de Suppression. Vous pouvez avoir besoin de spécialiser les tables liées options autour de ce comme éteindre CascadeOnDelete:
Ou désactiver cette fonctionnalité complètement:
Ma solution à ce problème rencontré dans l'utilisation ASP.NET Core 2.0 et EF Core 2.0 est à effectuer les opérations suivantes dans l'ordre:
Exécuter
update-database
de commande dans le Paquet de la Console de Gestion (PMC) pour créer la base de données (ce résultat "de l'Introduction de la contrainte de CLÉ ÉTRANGÈRE ... peut causer des cycles ou en cascade de plusieurs chemins." erreur)Exécuter
script-migration -Idempotent
commande PMC pour créer un script qui peut être exécuté indépendamment des tables existantes et des contraintesPrendre le script obtenu et trouver
ON DELETE CASCADE
et de le remplacer avecON DELETE NO ACTION
Exécuter la modification de SQL sur la base de données
Maintenant, les migrations doivent être à jour et les suppressions en cascade ne devrait pas se produire.
Dommage que je n'était pas en mesure de trouver un moyen de le faire dans Entity Framework Core 2.0.
Bonne chance!