2010-01-11 3 views
8

J'ai cette erreur bizarre Cannot add an entity with a key that is already in use Mais ce qui est assez irritable à propos de cette erreur, c'est que l'utilisateur ne reçoit aucune erreur - Qui? Quelle? Quelle table? Quel record est le coupable de cette erreur?Impossible d'ajouter une entité avec une clé déjà utilisée

Il serait désespérément compliqué de déterminer, au cas où vous faites de nombreuses opérations sur les objets LINQ avant .Submit()

Est-il possible de déterminer ce qui a causé certainement cette erreur?

Répondre

0

Il semble que vous effectuiez une Table.Attach() et que l'entité que vous attachez possède une valeur clé que L2S est déjà en train de suivre. Cela n'a rien à voir avec une clé en double dans votre base de données physique.

+2

Pas d'actions grossières avec les tables (attacher, détacher quoi que ce soit). Mais encore obscurcir pourquoi cette exception est levée Si j'avais plus d'informations détaillées sur l'exception, je serais en mesure de savoir quel code doit être modifié – igor

10

Cette erreur se produit généralement lorsque vous créez un nouvel enregistrement dans un MetaTable avec une relation de clé étrangère et que l'enregistrement de clé étrangère existe déjà. Par exemple, supposons que vous ayez une table Contact et une table d'adresses, et que chaque contact puisse contenir plusieurs adresses. L'erreur se produit lorsque vous créez un nouvel enregistrement de contact et essayez d'associer manuellement un enregistrement d'adresse existant à ce nouveau contact.

En supposant que le passé ID d'adresse représente un enregistrement d'adresse existante, cela ne fonctionne pas:

public class Contact 
{ 
    public int Contact_ID { get; set; } 
    public string Name { get; set; } 
    public Address ContactAddress { get; set; } 
    public string Phone { get; set; } 
} 

public class Address 
{ 
    public int Address_ID { get; set; } 
    public string Street { get; set; } 
    public string CityState { get; set; } 
    public string ZIP { get; set; } 
} 

public void CreateNewContact(int addressID) 
{ 
    Contact contact = new Contact(); 

    contact.Name = "Joe Blough"; 
    contact.ContactAddress.Address_ID = addressID; 
    contact.Phone = "(555) 123-4567"; 

    DataContact.SubmitChanges(); 
} 

Historiquement, les développeurs SQL sont formés pour passer juste la valeur d'identité pour que la magie se produire. Avec LINQ-to-SQL, parce que l'activité de base de données est abstraite, nous devons passer l'objet entier pour que le moteur LINQ puisse refléter correctement les changements nécessaires dans le ChangeSet. Dans l'exemple ci-dessus, le moteur LINQ suppose que vous demandez à créer un nouvel enregistrement d'adresse, car il n'avait pas d'interface avec les modifications SubmitChange et il doit respecter le contrat établi par la relation de clé étrangère. Il crée un enregistrement d'adresse vide avec la valeur d'ID transmise. L'erreur se produit car cette valeur d'ID existe déjà dans la table de données et le ChangeSet n'a pas marqué le delta d'adresse en tant que mise à jour.

La solution est de passer dans le dossier, et pas seulement la valeur ID:

contact.ContactAddress = DataContext.Addresses.Where(a => a.Address_ID == addressID).Single(); 

Maintenant, le moteur LINQ peut correctement signaler un dossier d'entrée d'adresse en tant que l'un et non existant essayer de le recréer.

1

Peut être la colonne que vous essayez de Attach(), Remove(), Add() ou DeleteOnSubmit(), est une clé primaire et que vous essayez d'ajouter ou de joindre à nouveau la même valeur.

Vous pouvez également accéder à une colonne de valeur de clé primaire ou de clé étrangère dans une méthode différente et elle n'est pas encore fermée lorsque vous essayez d'appeler les méthodes ci-dessus.

Au-dessus de ces méthodes Attach(), Remove(), Add() ou DeleteOnSubmit(), essayez de créer une nouvelle instance de votre datacontext à nouveau et exécuter.

0

Comme expliqué sur l'une des réponses ci-dessus, cette erreur est probablement due à la tentative d'insertion d'un enregistrement dans la table avec une valeur répétée sur le champ de clé ID primaire. Vous pouvez résoudre le problème en sélectionnant/créant une clé primaire différente.

Questions connexes