2012-04-03 16 views
28

Ehi Ho un'applicazione con una serie di caching inproc e framework di entità. Quando voglio scrivere un aggiornamento a un'entità, ricollego la copia cache. Traccio tutte le cose che ho allegato nel ciclo di vita del contesto, quindi non provo a collegarle due volte.Entity Framework: violazione di un vincolo di integrità referenziale in relazione molti a molti

ho un errore che si verifica sulla allegare (molto raramente nella maggior parte dei casi questo funziona bene ed è veramente veloce), che dice quanto segue:

Una violazione vincolo di integrità referenziale si è verificato: la proprietà valori che definiscono il i vincoli referenziali non sono coerenti tra tra principale e oggetti dipendenti nella relazione.

Ho guardato con attenzione l'entità che sembra normale. Penso che questo problema sia dovuto all'allegato/al distacco di una chiave esterna durante l'esecuzione delle correzioni.

C'è un buon modo per ottenere ulteriori informazioni su questo errore o può verificarsi per motivi diversi da quello che l'entità era in uno stato che EF non si aspettava?

EDIT: DB Schema (nota sto usando codefirst Ho appena utilizzato lo strumento EDMX per rendere lo schema, ho tritato anche un gruppo di proprietà regolari dal modello per semplicità)

enter image description here

+0

Stai utilizzando il codice prima o il modello per primo - e altre informazioni sul modello che hai, tabelle/classi relative all'errore e come sono mappati molti a molti. Nel caso tu stia utilizzando il codice per primo, preferisco fare la relazione "manualmente" in modo da poter controllare tutti gli aspetti ed evitare cose simili. Dall'altro lato, l'errore di integrità referenziale è probabile che significhi solo questo: non penso che sia lo stato dell'oggetto, anche se potrebbe manifestarsi in un modo simile a quanto immagino. – NSGaga

+0

Sto usando CodeFirst, il mio modello è davvero semplice, mal postare un diagramma in un secondo –

+0

Luke, puoi dare la parte CF, come mappare le cose - come sono le tue classi modello, il tuo codice di migrazione? Essere in grado di aiutare chiunque con questo. – NSGaga

risposta

40

L'errore potrebbe verificarsi per la relazione uno-a-molti tra Person e Location apparentemente nel modello oltre alla relazione molti-a-molti. Ad esempio, il seguente codice sarebbe generare l'eccezione:

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

"I valori delle proprietà che definiscono i vincoli referenziali" sono il valore della proprietà chiave esterna CurrentLocationId e il valore della chiave primaria CurrentLocation.Id. Se questi valori sono diversi, viene generata l'eccezione. (Avere come consentito.)

A mio parere, questa eccezione può essere generata solo per le associazioni di chiavi esterne perché solo per questo tipo di associazione si hanno proprietà che definiscono i vincoli referenziali nel proprio modello. Non può essere lanciato per associazioni indipendenti. Poiché ogni relazione molti-a-molti è un'associazione indipendente (nessuna proprietà di chiave esterna nel modello), suppongo che l'errore non sia correlato alla relazione molti-a-molti, ma alla relazione uno-a-molti.

+1

Quindi, come faccio a impostare il 'Location's su' Person's (dato l'ID 'Location's)? Nel mio scenario è un problema da molti a molti. Qual è la soluzione generale a questa eccezione, come faccio ad aggirarla? – Shimmy

+1

@Shimmy: imposta la proprietà FK solo lasciando la proprietà di navigazione come 'null' (cosa che farei in questo caso) o assicurati che il valore della proprietà FK e il valore PK dell'entità impostata sulla proprietà di navigazione siano gli stessi. Ma nella mia comprensione questa eccezione non può verificarsi per le relazioni molti-a-molti. È un'eccezione relativa alle sole associazioni FK e le relazioni molte-a-molti sono associazioni indipendenti, non associazioni FK. – Slauma

+0

Nel mio scenario ho 'Category's e' Business'. Ogni azienda può avere più 'categorie'.Ho una lista degli ID di categoria che voglio allegare, come faccio? – Shimmy

2

Ho appena sperimentato lo stesso problema e la risoluzione per il mio era che avevo aggiunto associazioni all'associazione e quindi impostare i referti referenziali.

Inorder per risolvere il problema, ho dovuto aprire la finestra dei mapping per l'associazione e c'era un collegamento per eliminare i mapping. Una volta eseguita la finestra Dettagli di mappatura, i Mapping non sono consentiti. Sembra che l'aggiunta del vincolo referenziale lasci posizionare qualsiasi mappatura.

Pensare che valga la pena di postare nel caso in cui qualcun altro stia cercando soluzioni a questo messaggio di errore in futuro.

1

@LukeMcGregor hi,

credo di poter offrire una prospettiva diversa come qualcuno che ha lo stesso problema.

Dopo aver eseguito tutti i controlli necessari, posso dire che preferisco ottenere questo errore.

Perché nel mio scenario: volevo includere un oggetto che ha causato un errore di disallineamento. È l'oggetto posizione nel tuo scenario. Se aggiungo un oggetto con un ID, ottengo questo errore perché l'ID nell'oggetto precedente (quello non aggiornato) non corrisponde all'ID aggiornato.

Ma non è un grosso problema. Come soluzione; Se è ancora sul lato dell'interfaccia utente, l'oggetto può ancora essere incluso se ancora esiste.

Si svuoterà l'oggetto quando si riceve la richiesta di aggiornamento da parte dell'utente. (= Null) O aggiornerai l'oggetto con l'ID aggiornato dall'utente prima dell'aggiornamento del servizio (allegare, modificato ... qualunque cosa) e aggiornarlo in questo modo.

Questo è tutto. Può rimanere com'è nel database e nei diagrammi.

1

mi sono imbattuto in un'eccezione molto simile:

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

Il motivo era questo: Il lato client delle API web ha inviato una richiesta PUT con l'intero oggetto inclusa la proprietà di navigazione (in questo esempio Objecta (più correttamente ObjectB.ObjectA) era una proprietà di navigazione ed era completamente fornita dal client). Ciò si verifica perché il client riceve l'intero oggetto dal server e lo rimbalza così com'è tornato al server con piccole modifiche.

D'altra parte, ObjectB.PropertyY era stato appena modificato (questo era il motivo della richiesta PUT in primo luogo).

Poiché ObjectB.PropertyY era un riferimento allo stesso oggetto ObjectA (una chiave esterna), EF ha tentato di riconciliarlo e ha avuto esito negativo con l'eccezione precedente.

La soluzione era semplice:

ObjectB.ObjectA = null; 

prima delle SaveChanges() risolto questo completamente.

Spero che questo aiuti qualcuno.

Problemi correlati