DbUpdateException en SaveChanges si la clave externa secundaria ya existe - en Entity Framework Code First

[ Uso de Code First DbContext con Entity Framework 5.0 RC ]

Entidad con 2 propiedades de navegación / 2 claves externas

public class Compositon
{

    public string Id { get; set; }

    public string SimpletonId { get; set; }

    [ForeignKey("SimpletonId")]
    public Simpleton Simpleton { get; set; }

    public string CompanitonId { get; set; }

    [ForeignKey("CompanitonId")]
    public Companiton Companiton { get; set; }
}

Primer paso - SaveChanges to Empty Database Works

var composition = new Compositon();
compositon.Id = "UniquePrimaryKey";
var simpleton = new Simpleton();
// This foreign key does not exist in database yet
simpleton.Id = "Simpleton1";
composition.Simpleton = simpleton;
var companiton = new Companiton();
companiton.Id = "SomeOther1";
composition.Companiton = companiton;
// Repositor references the DbContext
Repositor.Compositons.Add(composition);
Repositor.SaveChanges();

Segundo paso: la clave externa secundaria existente conduce a un error principal

var composition = new Compositon();
compositon.Id = "AnotherUniquePrimaryKey";
var simpleton = new Simpleton();
// This foreign key already exists in database
simpleton.Id = "Simpleton1";
composition.Simpleton = simpleton;
var companiton = new Companiton();
companiton.Id = "SomeOther2";
composition.Companiton = companiton;
Repositor.Compositons.Add(composition);
Repositor.SaveChanges();

DbUpdateException: An error occurred while updating the entries.

Necesito poder guardar estas clases principales en la base de datos, porque son únicas, aunque a veces contienen una propiedad de navegación que ya está almacenada. ¿Cómo puedo salvar al padre de este conflicto de clave principal secundaria?

preguntado el 12 de junio de 12 a las 15:06

1 Respuestas

En la segunda pasada necesitarás recuperar el existente Simpleton del desplegable DbContext. Supongo que podrías hacerlo así:

`simpleton = Repositor.Simpletons.First(s => s.Id == "Simpleton1");`

Actualmente, está creando uno nuevo, que Entity Framework intenta insertar como tal, de ahí la violación de clave.

Respondido el 12 de junio de 12 a las 15:06

¡Por supuesto! El reemplazo fue var simpleton = Repositor.Simpletons.Find("Simpleton1"); if (simpleton == null) { simpleton = new Simpleton(); simpleton.Id = "Simpleton1"; } - Sin embargo, esperaba que esto se hiciera de forma automática, ahora tengo que implementar este procedimiento tantas veces como propiedades secundarias tenga... - Cel

Podrías agregar un FirstOrNew(string id) método de extensión para IEnumerable<T> where T : IIdentifierOwner, new y utilícelo en su lugar. IIdentifierOwner tendría una cadena Id propiedad que se puede adquirir y establecer... - steve wilkes

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.