2011-11-19 9 views
5

He leído muchas preguntas aquí que al principio parecen tener un problema similar pero no parecen ser las mismas. Disculpas masivas si esto se responde en alguna parte, pero como dije, he leído mucho y no puedo encontrar una respuesta.Violación de la clave principal al agregar la relación de muchas a muchas tablas vinculadas en el marco de la entidad MVC 3

estoy usando Entity Framework y MVC 3. Estoy tratando de añadir etiquetas a los productos en mi marco de la entidad, que tienen una relación de muchos a muchos y una mesa de vinculación con simplemente las dos llaves en la mesa de enlace , entonces EF condensa las Etiquetas en una propiedad del Producto. Mesas están dispuestas de este modo:

producto: ProductID [int, clave primaria], nombre, etc.

Etiquetas: TagName [cadena, clave primaria]

Produto: ProductID, TagName

Así

acceder a Produto que sólo puede utilizar product.Tags

Este es mi código:

dbProduct.Tags.Clear(); 
foreach (var tag in productModel.Tags) 
{ 
    Data.Tag dbTag = new Data.Tag(); 
    dbTag.TagName = tag; 
    dbProduct.Tags.Add(dbTag); 
} 

dbProduct es una entidad de producto y los datos son el espacio de nombre. productModel.Tags es un List<string>

Cuando SaveChanges() consigo la siguiente excepción:..

"Violación de restricción PRIMARY KEY 'PK_Tags_1' No se puede insertar clave duplicada en 'dbo.Tags' objeto \ r \ nLa declaración ha sido terminada. "

Así que lo que realmente me está atrapando es: ¿por qué está tratando de agregar algo a dbo.Tags? Me parece que esto debería simplemente agregar etiquetas ProductTags no. No menciono las etiquetas en ningún otro lugar de este método y, por lo tanto, en ningún momento intento agregar nada directamente en la tabla Etiquetas. Siento que puedo tener algo mal configurado en mi EF, pero no puedo pensar qué y fue generado desde la base de datos.

Perdón nuevamente si esto es cegadoramente obvio, me estoy sintiendo bastante estúpido. Cualquier ayuda muy apreciada.

Respuesta

11

El problema es que está creando un nuevo objeto Tag con una clave principal existente. Cuando se llama SaveChanges(), EF detecta los cambios de las entidades que ya están rastreando y las nuevas entidades agregadas. Dado que su nuevo objeto Tag no fue rastreado por EF, intenta insertarlo.

Debe indicar explícitamente a EF que la etiqueta creada es una existente. Para hacer eso, necesita attach.

dbProduct.Tags.Clear(); 
foreach (var tag in productModel.Tags) 
{ 
    Data.Tag dbTag = new Data.Tag(); 
    dbTag.TagName = tag; 

    db.TagSet.Attach(dbTag); 

    dbProduct.Tags.Add(dbTag); 
} 

Este código se supone que no va a instalar una sola etiqueta varias veces y todas las etiquetas son etiquetas existentes.

+0

Oh, señor, gracias. Estuve jugando con Attach, pero no entiendo cómo funciona. Eso lo solucionó. Lamentablemente, no puedo 'Votarte' ya que estoy recién inscripto, pero gracias. Tienes un buen karma en camino. – Smeats

+0

@ user1054799 genial. Puede marcar esto como la respuesta aceptada :) – Eranga

+0

Listo. Gracias de nuevo. – Smeats

Cuestiones relacionadas