LINQ-to-SQL + Un-à-Plusieurs + suppression de la liaison de données
- Je utiliser LINQ-to-SQL pour charger des données depuis une base de données qui a deux tables dans une relation (une Recette a beaucoup d'Ingrédients).
Je charge une Recette et LINQ récupère Ingrédient objets dans un EntitySet est lié dans une ListBox.
Si je veux supprimer certains Ingrédients hors de la Recette, j'obtiens un "Une tentative a été faite pour supprimer une relation entre une Recette et Ingrédients. Cependant, l'un de la relation de clés étrangères (Ingrédient.RecipeID) ne peut pas être null.
J'ai RÉSOLU ce problème en utilisant la bien connue de la solution en ajoutant 'DeleteOnNull="true"' pour le fichier DBML. Mais l'ajout de ce paramètre supprime uniquement le problème lorsque nous sommes à la suppression des Ingrédients les objets qui ont été récupérés à partir de la DB.
Le problème est avec l'Ingrédient objets qui ont été créés dans le code (pour une Recette) et ajouté à l'EntitySet collection des Ingrédients et puis supprimés AVANT SubmitUpdates est appelé. Puis, la même exception se produit de nouveau. Cela se produit généralement sur une nouvelle, non enregistrées recette lorsque l'utilisateur est à ajouter des ingrédients à elle, fait une erreur et efface un ingrédient hors de la recette. J'ai ajouté le DeleteOnNull à la fois à " l'Association Nom="Recipe_Ingredient"' lignes dans DBML.
Comment suis-je censé supprimer de tels objets? La seule solution que je vois pour le moment est que je voudrais charger les ingrédients dans une collection n'est pas sous le DataContext et ensuite lors de l'enregistrement, supprimer tous les ingrédients hors de la recette et ajouter puis à nouveau à partir du cache..
Est-ce que votre nouveau Reciepe objet appartenant à un DataContext lorsque vous ajoutez/supprimez des Ingrédients objets?
non (lorsque la recette est nouveau) et oui (si c'est un existant, consulté le fron DB et d'avoir des ingrédients ajoutés).
OriginalL'auteur Jurij | 2008-12-21
Vous devez vous connecter pour publier un commentaire.
Le code ci-dessus les poignées de nouvelles non validées ceux qui ont été créés et supprimés de la mémoire (ce n'est pas un exemple de code - j'ai littéralement copié et collé le code à partir d'une production en direct app et modifié les noms de types et variables). Avez-vous appeler InsertOnSubmit lorsque vous avez initialement créé l'ingrédient?
Vous l'avez fait! J'ai fait ajouter le nouvel Ingrédient objet dans l'EntitySet recouvrement d'une Recette de l'objet, mais n'appelle pas InsertOnSubmit comme il semblait ne rien faire. Mais votre proposition résout le problème. Merci beaucoup!
OriginalL'auteur mjwills
Il semble que vous êtes à la recherche de quelque chose que je cherchais moi-même seulement quelques jours en arrière quand j'ai demandé "Comment concevoir la sauvegarde des types de données pour un databound WPF dialogue avec les boutons Ok/Annuler?".
La réponse est un intrigant post de Paul Stovell décrivant un échantillon IEditable adaptateur pour Linq to Sql. Cela vous permettra de créer vos souhaité "Appliquer/Annuler" de la sémantique d'une façon généralisée, sans dissocier complètement vous-même à partir de la sous-jacentes ORm-classes générées à travers la pleine mesure de la couche.
C'est une jolie nappe de truc, dans l'ensemble, qui sera essentiellement vous permettre d'éviter les problèmes que vous affrontez maintenant. 🙂
Sur une autre note, je suis curieux de savoir pourquoi votre recette ingrédient relation 1:n à la place de m:n. Est-ce par souci de simplicité? J'ai utiliser de l'ail dans un grand nombre de recettes. 🙂
OriginalL'auteur Greg D
Explication du problème: les Deux entités, c et ce ne sont pas liés à un contexte de données - qu'elles ne sont pas suivies. EntitySet.Remove() (première ligne supprimer) supprime uniquement la relation entre c et ec. Alors que c peut exister sans associé panier entrées, ce ne peut pas exister sans un assiciated cart en raison d'une contrainte de clé étrangère. Lors de la présentation des modifications à la base de données, le déconnectée ce est traitée ainsi, provoquant une violation de la contrainte et de l'exception.
Afin de se débarrasser de que sans traces et déconnecté panier entrées, vous devez joindre à votre contexte de données (à l'origine pour être suivies à la trace) puis le marquer pour suppression sur "soumettre". Le moment où vous soumettez vos modifications le chariot d'entrée sera supprimé correctement et de ne pas provoquer l'exception.
Pour plus de détails sur cette question check this out:
http://msdn.microsoft.com/en-us/library/bb546187%28v=VS.100%29.aspx
OriginalL'auteur TexTheAfk
vous avez besoin pour découpler le sauver de code à partir des événements dans votre interface utilisateur graphique, il semble que vous êtes un peu à la hâte pour enregistrer les choses de la db avant que la poussière est retombée et que vous êtes d'attente et de retrait de choses à partir de la db qui n'ont jamais obtenu il y a, en premier lieu, il serait mieux si vous pouviez identifier un point lorsque l'utilisateur "s'engager" leurs changements, et à ce moment, le processus de la condition complète de l'interface graphique - cela vous fera économiser un tas de code spaghetti.
Je serais également curieux de savoir si votre entités ont numéroauto Identifiants ou si vous êtes en utilisant un autre ID mécanisme. Vous êtes probablement l'envoi Supprime de la base de données n'a pas encore été validées Ingrédient enregistrements, si ceux-ci contiennent la valeur NULL Id, je pense que le linq pourrait se gâter.
Avez-vous branché un textwriter à votre DataContext.Le journal pour voir quelles sortes de SQL est généré juste avant que vous obtenez votre exeception?
OriginalL'auteur Andrew Theken
Je vous remercie pour votre réponse, je vais examiner les posts et voir ce que je peux faire. Je dois dire que je suis surpris de le voir même ce problème survenant, il semble tout à fait naturel pour moi que l'on pouvait ajouter des enregistrements à la LINQ-fourni "cache" de données, puis de décider d'effacer certains d'entre eux, puis valider. Le suivi des modifications doivent être capable de gérer cela. Je viens de commencer avec LINQ donc j'ai peut être fait une erreur stupide, quelque part dans le code (qui ne serait pas le premier).
Sur l'autre note: Vous êtes tout à fait exact que l'ail peut appartenir à de nombreuses recettes (pas mon cocktail-recettes a pensé!). J'ai effectivement modèle avec un Article de l'objet/de la table. Mais pour une recette, vous avez besoin de quantités. Donc, dans mon modèle, vous avez une Recette qui a 1:n Ingrédients, chacun d'eux ayant une Quantité de 1:1 lien vers un Article (qui a un Nom, un AlcoholContent et certaines données pour établir une interchangeabilité de la hiérarchie) et un rapport de 1:1 lien vers une Unité (pour la quantité à donner un sens).
Donc dans un sens, Ingrédient table est un M:N relation entre la Recette et de l'Article, et en même temps, en ajoutant des informations supplémentaires pour chaque individu lié paire.
OriginalL'auteur Jurij
J'ai eu exactement le même problème. J'ai eu un parent /enfant, la hiérarchie, et lors de l'ajout et de retrait de l'enfant de l'entité sans l'enregistrer dans la base de données, j'ai reçu la "Une tentative a été faite pour supprimer une relation" d'exception.
J'ai découvert que ce problème ne se pose lorsque j'ai mis un objet de style de la propriété de l'enfant à l'autre linq-sql entité avant de l'enregistrer. par exemple
1. Cela crée une erreur
2. Ce n'est pas de créer l'erreur
Curieusement, l'erreur qui se produit dans de 1. spécifie le problème est de le faire avec la relation est sur le RetailAccountCustomerId propriété de RetailAccountCustomerCard. IL n'A RIEN à faire avec la Carte de l'objet, j'ai ajouté. Il semble que le simple réglage de tout propriété de l'objet de la nouvelle entité déclenche le problème.
NB. Exemple 1 fonctionne très bien en termes d'économie, il ne provoque un problème si la nouvelle entité est supprimée avant de l'enregistrer.
Avez-vous trouvé une solution pour cela?
Je n'ai jamais fait, non. Si vous arrivez à la Tour Sombre, s'il vous plaît revenir et laissez-nous savoir, hein? 😉
Merci pour votre réaction. Il semble que j'ai trouvé la solution moi-même: social.msdn.microsoft.com/Forums/en/linqtosql/thread/... de Longues journées et des nuits agréables...
OriginalL'auteur
Je suis confronté à un problème similaire, comme une solution de contournement, j'ai besoin d'appeler le DataContext.GetChanges(), alors tout semble avoir pris à nouveau 🙂
Un autre problème que vous pourriez avoir, ce que vous êtes de liaison à colonnes et pas de propriétés d'entité, et donc le référentiel des collections ne sont pas mis à jour (déjà dit par quelqu'un d'autre, mais l'application de la circonstance).
OriginalL'auteur leppie