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.
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