Este error suele ocurrir cuando se crea un nuevo registro en una metatabla con una relación de clave externa y el registro de clave externa ya existe.
Por ejemplo, supongamos que tiene una tabla de contactos y una tabla de direcciones, y cada contacto puede contener varias direcciones. El error ocurre cuando crea un nuevo registro de Contacto e intenta asociar manualmente un registro de Dirección existente a ese Contacto nuevo.
Suponiendo que la dirección de la identificación pasado representa un registro de dirección existente, esto no funciona:
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();
}
Históricamente, los desarrolladores de SQL están capacitados para simplemente pasar el valor de identificación a fin de que la magia suceda. Con LINQ-to-SQL, debido a que la actividad de la base de datos se abstrae, tenemos que pasar todo el objeto para que el motor LINQ pueda reflejar adecuadamente los cambios necesarios en ChangeSet. En el ejemplo anterior, el motor LINQ supone que está solicitando crear un nuevo registro de Dirección, porque no tenía uno con el que trabajar cuando se realizó el Envío de Cambios y tiene que respetar el contrato establecido por la relación de clave externa. Crea un registro de dirección en blanco con el valor de ID pasado. El error se produce porque ese valor de ID ya existe en la tabla de datos y ChangeSet no ha marcado la dirección delta como una actualización.
La solución es pasar en todo el registro, no sólo el valor de ID:
contact.ContactAddress = DataContext.Addresses.Where(a => a.Address_ID == addressID).Single();
Ahora, el motor de LINQ puede destacar adecuadamente el registro de dirección de entrada como una ya existente y no tratar de volver a crearlo.
Sin acciones bruscas con las tablas (adjuntar, separar lo que sea). Pero aún no está claro por qué se lanza esta excepción Si tuviera más información detallada sobre la excepción, podría averiguar qué código debe modificarse – igor