2008-12-17 7 views
3

J'ai une application (ASP.NET 3.5) qui permet aux utilisateurs de relancer un processus particulier si nécessaire. Le processus insère des enregistrements dans une table MS SQL. J'ai l'insertion dans un Try/Catch et ignore la capture si un enregistrement existe déjà (l'erreur dans le titre serait valide). Cela a fonctionné parfaitement en utilisant ADO mais après avoir été convoqué à LINQ, j'ai remarqué une chose intéressante. Si lors d'une nouvelle exécution du processus il y avait déjà des enregistrements dans la table, tous les nouveaux enregistrements seraient rejetés avec la même erreur, même s'il n'y avait aucun enregistrement existant. Le code est le suivant:LINQ: Impossible d'insérer la ligne clé dans l'objet « dbo.tblOutstandingCompletions » avec index unique

  Dim ins = New tblOutstandingCompletion 
      With ins 
       .ControlID = rec.ControlID 
       .PersonID = rec.peopleID 
       .RequiredDate = rec.NextDue 
       .RiskNumber = 0 
       .recordType = "PC" 
       .TreatmentID = 0 
      End With 

      Try 
       ldb.tblOutstandingCompletions.InsertOnSubmit(ins) 
       ldb.SubmitChanges() 
      Catch ex As Exception 
       ' An attempt to load a duplicate record will fail 
      End Try 

DataContext pour la base de données a été créée au cours de chargement de la page.

je résolu le problème en redéfinissant le DataContext avant chaque insertion:

 ldb = New CaRMSDataContext(sessionHandler.connection.ToString) 
     Dim ins = New tblOutstandingCompletion 

Bien que j'ai résolu le problème que je voudrais savoir si quelqu'un peut l'expliquer. Sans la redéfinition DataContext, l'application fonctionne parfaitement s'il n'y a pas d'enregistrements en double.

Cordialement James

+1

Quelle est votre clé primaire sur la table? On dirait que vous insérez le disque deux fois au cours d'une demande ... – Will

+0

La clé primaire est un entier avec IsIdentity spécifié. L'autre index du fichier est constitué de 5 champs.Les enregistrements qui tentaient d'être ajoutés étaient définitivement uniques. J'ai essayé la même application sur deux versions différentes de la db avec des données très différentes et j'ai obtenu le même résultat. –

Répondre

1

Il semble que le DataContext pense que le record a été inséré la première fois, donc si vous ne redéfinissez pas le contexte, il rejette la deuxième insert parce qu'il « sait » le dossier est déjà là . Redéfinir le contexte l'oblige à vérifier la base de données pour voir si elle est là, ce qu'elle n'est pas. LINQ essaie d'enregistrer un aller-retour dans la base de données. Créer un nouveau contexte comme vous l'avez fait l'oblige à réinitialiser ce qu'il "sait" sur la base de données.

2

J'avais vu un problème très similaire dans mon code où la colonne identité n'était pas une colonne int auto-incrémentée, mais un GUID avec une valeur par défaut newguid() - LINQ ne permettait pas à la base de données de créer le GUID , mais en insérant Guid.Empty à la place, et la deuxième (ou plus tard) tentatives (correctement) lancer cette erreur.

Je fini par faire en sorte que je généré un nouveau moi-même GUID au cours de l'insertion. Plus de détails peuvent être vus ici: http://www.doodle.co.uk/Blogs/2007/09/18/playing-with-linq-in-winforms.aspx

Cela m'a permis d'insérer plusieurs enregistrements avec le même DataContext.

Également, avez-vous essayé d'appeler InsertOnSubmit plusieurs fois (une fois pour chaque nouvel enregistrement), mais en appelant une seule fois SubmitChanges?

1

gfrizzle semble être ici ...

Mon code échoue avec la clé doublon même si je n'ai plus juste un proc stocké tronquer la table sur la base de données. Pour autant que le contexte de données le sache, l'insertion précédente d'un enregistrement avec la même clé est en fait une clé dupliquée et une exception est levée.

La seule façon que je l'ai trouvé autour de c'est:

 db = null; 
     db = new NNetDataContext(); 

juste après les SubmitChanges() qui exécute les demandes de InsertOnSubmit précédentes. Cela semble un peu stupide, mais c'est la seule façon qui fonctionne pour moi autre que la refonte du code.

Questions connexes