69 votes

System.Data.Linq.ChangeConflictException : Row non trouvé ou modifié

J'essaie de supprimer une ligne sélectionnée d'un gridview en utilisant LINQ (No LINQDataSource).

Lorsque la sélection est modifiée, la liaison de la vue détaillée est modifiée. également. Je peux ajouter une nouvelle entrée dans la base de données, mais lorsque j'ai ajouté ce code à un bouton de suppression dans le panneau de mise à jour, j'ai obtenu une exception :

try
{           
    var query = from i in db.QuestionModules 
                where i.QuestionModuleID == QuestionModuleID 
                select i;

    QuestionModule o = query.First();
    db.QuestionModules.DeleteOnSubmit(o);
    db.SubmitChanges();
}

C'est l'exception que je reçois :

System.Data.Linq.ChangeConflictException: Row not found or changed. at
System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode
failureMode) at
System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges() 

J'ai ce problème depuis environ une semaine, et quoi que je fasse, il est toujours présent, et l'enregistrement n'est pas supprimé.

Des idées sur ce qu'il faut faire ?

71voto

Mark Points 5924

OK - il semble que (dans mon cas du moins) la réponse était de définir tous propriété UpdateCheck de la colonne non clé primaire pour Jamais dans le fichier DBML. Cette opération a permis de résoudre immédiatement le problème du "Row not found or changed".

Compte tenu de la rumeur selon laquelle Microsoft se débarrasse de Linq-To-Sql au profit d'Entity Framework, on peut se demander si ce genre de bogues sera corrigé ?

0 votes

+1 comme cela a fonctionné. quelqu'un peut-il nous éclairer sur les implications de ceci. Un article de blog ou autre serait formidable. Merci.

8 votes

Comme indiqué dans l'autre réponse de Mark, cela fonctionne parce que certains types (tels que les datetime2 avec une grande précision) ne sont pas transférés correctement entre le serveur et le client et la méthode de Linq-To-SQL, qui ne peut être utilisée qu'en cas de besoin. concurrence optimiste pense que la perte de précision dans le marshaling erroné est un signe que la base de données a mis à jour sa valeur et abandonne l'action. Si l'on passe à Never empêche la vérification optimiste de la concurrence pour qu'elle réussisse (correctement dans ce cas).

63voto

SemMike Points 595

Vous obtenez cette erreur très probablement parce que l'un de vos champs a une valeur différente dans le concepteur Linq To SQL et dans la base de données réelle.

Dans mon cas, c'était parce que l'un des champs était annulable dans la base de données et non dans le concepteur. Le fait de le rendre également annulable dans le concepteur a résolu le problème immédiatement.

4 votes

L'inadéquation entre la DBML et la base de données était également mon problème.

0 votes

Oui, c'est ce que je pensais. J'imagine qu'une recommandation visant à attribuer une valeur à "toutes" les colonnes a recueilli plus de votes :(

0 votes

Oui, c'est la vraie réponse.

15voto

Mark Points 5924

J'ai le même problème, et je suis tombé sur ce blog qui dit en substance que Linq-To-Sql a un problème de concurrence optimiste :

  1. Des champs de date de haute précision sont utilisés. La solution est de mettre UpdateCheck à jamais pour cette colonne dans votre fichier DBML.
  2. Les colonnes GridView qui sont définies comme invisibles accèdent à une propriété de l'objet de données (cette deuxième raison n'a aucun sens, mais elle semble faire fureur sur ce blog).

Je n'ai pas encore essayé ces solutions, mais j'en ferai part ici dès que ce sera le cas.

0 votes

OK - Je viens d'essayer de régler l'UpdateCheck de toutes les colonnes de date sur Never... sans succès, j'obtiens toujours le même résultat.

1 votes

J'ai eu le même problème avec la mise à jour d'un champ de type datetime : le changement de la valeur UpdateCheck a résolu le problème.

2 votes

float dans la base de données SQL, que j'avais mappé sur un champ float (simple) type en C#. Lorsque j'ai changé le type en double le problème a disparu. Mais c'est votre réponse qui m'a mis la puce à l'oreille - alors MERCI !

13voto

Le problème pourrait aussi être simplement que la définition DBML de la table n'est pas cohérente avec le statut de la définition de la base de données. J'ai simplement supprimé le modèle DBML et l'ai réinséré dans la base de données, et cela a fonctionné.

J'espère que cela aidera quelqu'un.

0 votes

C'est la meilleure réponse

0 votes

Cela a marché pour moi. J'ai essayé de vérifier et d'ajuster manuellement la table DBML et, bien qu'elle ait l'air identique, seule la suppression et le redéplacement de la table dans la DBML ont fonctionné pour moi.

6voto

Travis Points 158

Cela a semblé fonctionner pour ma situation aussi. Je construisais une ligne en mémoire, jamais soumise auparavant, qui avait plusieurs relations de clé étrangère avec des lignes d'autres tables. L'InsertOnSubmit semblait fonctionner mais un DeleteOnSubmit ultérieur me donnait l'erreur row not found. Je ne remplissais pas tous les champs de la ligne que je soumettais, je ne sais donc pas si cela avait un rapport avec le problème, mais le fait de marquer toutes les colonnes de la table principale qui ne sont pas des clés primaires a éliminé le message d'erreur.

Une autre réflexion : Je suppose que le fait de marquer la politique UpdateCheck d'une colonne comme "Jamais" signifie qu'elle n'est pas utilisée comme base pour la vérification optimiste de la concurence. Cela signifierait que deux utilisateurs pourraient écrire sur une ligne donnée avec des données différentes dans une telle colonne et que les conflits ne seraient pas détectés... ce qui signifie que le dernier utilisateur à soumettre la ligne écraserait les valeurs de la soumission de l'utilisateur précédent. J'ai compris, en lisant divers documents en ligne, qu'une solution partielle à ce problème consiste à utiliser la méthode Refresh immédiatement avant la soumission pour synchroniser les changements. Bien sûr, sans verrou pesimiste sur la ligne, il n'y a aucune garantie que la ligne ne sera pas encore modifiée entre le rafraîchissement et la soumission, mais dans la plupart des scénarios impliquant de grandes bases de données, cela serait rare.

Mise à jour : Après un examen plus approfondi, je pense avoir découvert un scénario qui peut affecter d'autres personnes. J'ai donc pensé que je devais le partager au cas où. Il s'avère qu'au moins une partie des problèmes que j'ai rencontrés avec SQL LINQ est liée aux déclencheurs. Il semble que si vous soumettez une ligne en utilisant SQL LINQ et que votre DBA a des déclencheurs conçus pour écrire des informations dans certaines colonnes de cette ligne, le modèle SQL LINQ déterminera par défaut que la ligne a été modifiée depuis votre dernière écriture. J'ai soumis des lignes partiellement remplies et les déclencheurs de notre DBA remplissent certaines colonnes de sorte que lorsque j'ai essayé de modifier la ligne dans notre code, il a détecté un conflit de changement basé sur les colonnes remplies par le déclencheur. J'étudie actuellement la meilleure façon de gérer ce problème, mais le fait de modifier ces champs remplis par les déclencheurs pour utiliser une politique UpdateCheck de 'When Changed' ou 'Never' a fonctionné pour moi. J'espère que cela vous aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X