2009-04-28 10 views
5

J'ai une table qui ressemble à ce qui suit:Linq2SQL traiter avec insertions/suppressions sur la table avec des contraintes uniques

TABLE Foo 
{ 
    Guid Id [PK], 
    int A [FK], 
    int B [FK], 
    int C [FK], 
} 

Et contrainte unique sur A, B et C.

dire maintenant, par exemple, vous insérez une ligne avec un nouveau PK avec A = 1, B = 1, C = 1.

SubmitChanges(), tous heureux.

Maintenant vous éditez la table.

Vous supprimer l'entrée précédente, et insérer une ligne avec un fresk PK avec A = 1, B = 1, C = 1.

SubmitChanges() BOOM! Exception SQL de contrainte de clé unique. D'après ce que je peux voir, il essaie d'insérer d'abord le nouvel enregistrement, puis essaie de supprimer le précédent. Je peux même comprendre qu'il n'est pas possible de déterminer l'ordre dans lequel cela doit se produire.

Mais que puis-je faire à ce sujet? Est-ce que faire de ces 3 champs un PK composite (et retirer l'ancien) serait une meilleure solution ou ne fonctionnera-t-il pas? Pour l'instant, la 'solution' consiste à supprimer les contraintes uniques de la base de données (mais je préfère ne pas le faire).

Répondre

3

Une option serait de créer une transaction (soit une transaction liée à la connexion, ou un TransactionScope) - supprimer l'enregistrement et SubmitChanges, ajouter l'enregistrement et SubmitChanges, puis enfin valider la transaction (ou roll-back si vous fait sauter en haut).

Notez que vous pouvez associer une transaction liée à une connexion via le constructeur de contexte de données IIRC. TransactionScope devrait également fonctionner, et est plus facile à faire - mais pas tout à fait aussi efficace.

Vous pouvez également écrire un SP qui exécute ce travail d'échange dans la base de données et accéder à ce SP via le contexte de données.

+0

Malheureusement pas si facile. La liste est maintenue via une BindingList, obtenue à partir d'un EntitySet lié à un DataGridView. – leppie

1

J'ai eu le même problème. J'ai fini d'écrire une classe wrapper avec une collection d'entités 'Added' et 'Deleted' que j'ai conservée. Ainsi qu'une collection "Actuelle". L'interface utilisateur était liée à la collection actuelle.

Seulement quand je vais enregistrer, je InsertOnSubmit/DeleteOnSubmit, et j'analyse les 2 collections pour décider quelles entités faire quoi.

+0

Merci pour la réponse (+1) Btw J'ai trouvé le plus simple est en fait juste envoyer des modifications en temps réel à la DB, alors cela ne peut arriver :) Une autre option pourrait être d'ajouter une transaction à ce qui précède si vous avez besoin '. – leppie

Questions connexes