2012-04-03 57 views
28

Hola, tengo una aplicación con un montón de inproc caching y entidad de marco. Cuando quiero escribir una actualización para una entidad, vuelvo a conectar la copia en caché. Rastreo todas las cosas que he adjuntado en el ciclo de vida del contexto, así que no intento adjuntarlas dos veces.Entity Framework: una violación de restricción de integridad referencial en la relación de muchos a muchos

Tengo que ocurre un error en colocar (muy raramente en la mayoría de los casos esto funciona bien y es muy rápido), que dice lo siguiente:

Un referencial violación de restricción de integridad ocurrió: La propiedad valores que definen el las restricciones referenciales no son consistentes entre objetos principales y dependientes en la relación.

He echado un vistazo muy cuidadoso a la entidad que parece normal. Creo que este problema se debe a la conexión/desacoplamiento de una clave externa cuando se ejecuta la reparación.

¿Hay una buena manera de obtener más información sobre este error o puede ocurrir por otras razones que la entidad estaba en un estado que EF no esperaba?

EDIT: Diagrama DB (tenga en cuenta que estoy usando codefirst acabo de utilizar la herramienta EDMX para hacer el diagrama, también he picado un montón de propiedades regulares fuera el modelo de simplicidad)

enter image description here

+0

¿Está utilizando el código primero o el modelo primero, y más información sobre el modelo que tiene, las tablas/clases que se relacionan con el error y cómo se mapean los muchos a muchos? En caso de que esté usando el código primero, prefiero hacer la relación 'manualmente' para que pueda controlar todos los aspectos y evitar cosas similares. Por otro lado, es probable que el error de integridad referencial signifique exactamente eso: no creo que sea el estado del objeto, aunque podría manifestarse de forma similar, supongo. – NSGaga

+0

Estoy usando CodeFirst, mi modelo es muy simple, me gustaría publicar un diagrama en un sec –

+0

Luke, ¿puedes dar la parte CF, cómo mapear cosas, cómo son tus clases modelo, tu código de migraciones? Para poder ayudar a cualquiera con esto. – NSGaga

Respuesta

40

El error puede ocurrir por la relación de uno a muchos entre Person y Location que aparentemente tiene en su modelo, además de la relación muchos a muchos. Por ejemplo, el siguiente código emitir la excepción:

using (var context = new MyContext()) 
{ 
    var person = new Person 
    { 
     CurrentLocationId = 1, 
     CurrentLocation = new Location { Id = 2 } 
    }; 
    context.People.Attach(person); // Exception 
} 

"Los valores de las propiedades que definen las restricciones de referencia" son el valor de la propiedad de clave externa CurrentLocationId y el valor de clave principal CurrentLocation.Id. Si esos valores son diferentes, se lanza la excepción. (Después de haber CurrentLocation como null aunque está permitido.)

En mi opinión esta excepción sólo puede ser arrojado a las asociaciones de claves externas debido a que sólo para este tipo de asociación tiene propiedades que definen las restricciones de referencia en absoluto en su modelo. No se puede lanzar para asociaciones independientes. Dado que cada relación de muchos a muchos es una asociación independiente (ninguna propiedad de clave externa en el modelo), creo que el error no está relacionado con la relación de muchos a muchos, sino con el uno-a-muchos.

+1

Entonces, ¿cómo configuro 'Location's' 'Person's (dado el' Location's IDs)? En mi caso, es un problema de muchos a muchos. ¿Cuál es la solución general a esta excepción, cómo puedo evitarlo? – Shimmy

+1

@Shimmy: Establezca la propiedad FK solo dejando la propiedad de navegación como 'null' (lo que haría en este caso) o asegúrese de que el valor de propiedad FK y el valor PK de la entidad establecida en la propiedad de navegación sean los mismos. Pero, a mi entender, esta excepción no puede darse para relaciones de muchos a muchos. Es una excepción relacionada solo con asociaciones de FK y las relaciones de muchos a muchos son asociaciones independientes, no asociaciones de FK. – Slauma

+0

En mi escenario tengo 'Category's y' Business'. Cada empresa puede tener múltiples 'Categoría's.Tengo una lista de los ID de Categoría que quiero adjuntar, ¿cómo lo hago? – Shimmy

2

He estado experimentando el mismo problema y la resolución de la mía era que había agregado asignaciones a la asociación y luego configuré las contorsiones referenciales.

Para resolver el problema, tuve que abrir la ventana de asignaciones para la asociación y había un enlace para eliminar las asignaciones. Una vez hecha la ventana de Mapeo de detalles, dichas asignaciones no están permitidas. Parece que al agregar la restricción referencial deja las asignaciones en su lugar.

Pensamos que valdría la pena publicarlo en caso de que alguien más esté buscando soluciones a este mensaje de error en el futuro.

1

@LukeMcGregor hola,

creo que puedo ofrecer una perspectiva diferente como alguien que tiene el mismo problema.

Después de haber realizado todas las comprobaciones necesarias, puedo decir que prefiero obtener este error.

Porque en mi caso: quería incluir un objeto que causara un error de desajuste. Es el objeto de ubicación en tu escenario. Si agrego un objeto con una ID, obtengo este error porque la ID en el objeto anterior (la que no se actualiza) no coincide con la ID actualizada.

Pero no es un gran problema. Como una solución; Si aún está en el lado de la interfaz de usuario, el objeto aún puede incluirse si aún existe.

Vaciar el objeto cuando reciba la solicitud de actualización del usuario. (= Nulo) O actualizará el objeto con la ID actualizada por el usuario antes de la actualización del servicio (adjuntar, modificar ... lo que sea) y actualizarlo de esta manera.

Eso es todo. Puede permanecer tal como está en la base de datos y diagramas.

1

me encontré con una excepción muy similar:

"A referential integrity constraint violation occurred: 
The property value(s) of 'ObjectA.PropertyX' on one end of a relationship 
do not match the property value(s) of 'ObjectB.PropertyY' on the other end." 

La razón era la siguiente: El lado del cliente de la API de Web envía una solicitud PUT con el objeto entero incluyendo la propiedad de navegación (en este ejemplo Objecta (más correctamente ObjectB.ObjectA) era una propiedad de navegación y fue completamente suministrado por el cliente). Esto ocurre porque el cliente recibe el objeto completo del servidor y lo devuelve como está de vuelta al servidor con cambios menores.

Por otro lado, acaba de cambiarse ObjectB.PropertyY (esta fue la razón de la solicitud PUT en primer lugar).

Dado que ObjectB.PropertyY era una referencia al mismo objeto ObjectA (una clave externa), EF intentó conciliar esto y falló con la excepción anterior.

La solución fue simple:

ObjectB.ObjectA = null; 

antes de que los SaveChanges() resolvió este completamente.

Espero que esto ayude a alguien.

Cuestiones relacionadas