2010-08-01 15 views
10

mi stoEntity Framework e l'eredità: NotSupportedException

System.NotSupportedException: Tutti gli oggetti in 'Entities.Message' EntitySet devono avere unici chiavi primarie. Tuttavia, un'istanza di tipo 'Model.Message' e un'istanza di tipo 'Model.Comment' entrambi hanno lo stesso valore chiave primaria

ma non ho idea di cosa significa.

Utilizzando EF4, ho un gruppo di entità di tipo Messaggio. Alcuni di questi messaggi sono in realtà un sottotipo, Commento, ereditarietà per tabella per tipo. Solo

DB.Message.First(); 

produrrà l'eccezione. Ho altre istanze di sottotitoli in cui non ho problemi, ma non riesco a vedere alcuna discrepanza. A volte, tuttavia, il problema scompare se riavvio il server di sviluppo, ma non sempre.

Modifica: Ho elaborato (dovrebbe avere prima) che il problema è un errore della stored procedure durante il recupero dei messaggi. Il modo in cui è impostato attualmente come tutti i campi relativi a Messaggio viene recuperato, la tabella dei commenti viene ignorata dallo sproc. Il contesto procede quindi a rimuoverlo, probabilmente recuperando quei Messaggi che sono anche di nuovo Commenti, come suggerito. Come farlo correttamente è la questione centrale a portata di mano. Ho trovato alcune indicazioni per una soluzione al http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/bb0bb421-ba8e-4b35-b7a7-950901adb602.

+0

Puoi pubblicare le firme delle classi Messaggio e Commento? – Basic

+0

Scusa, non ti capisco. Vuoi vedere i membri? Tutti loro o solo quelli generati da EF? – Martin

+0

Hai controllato questo bug? https://connect.microsoft.com/VisualStudio/feedback/details/544639/ef4-inheritance-defined-using-queryview-doesnt-work-properly-with-association –

risposta

0

Non sono un tipo di ragazzo EF (impegnato a lavorare con NHibernate, non ho ancora avuto il tempo di aggiornarmi con EF) quindi potrei sbagliarmi completamente qui, ma il problema potrebbe essere che le due tabelle (dal momento che si utilizza l'ereditarietà da tabella per tipo) hanno le chiavi primarie che si scontrano?

Se si controllano i dati in entrambe le tabelle, i valori delle chiavi primarie si scontrano?

+0

Beh, sì, come dovrebbero. Se non mi credi, credi a EF. C'è un piccolo comando elegante chiamato "Crea database dal modello" ... – Martin

1

Sembra che stiate tirando due record in memoria uno nel messaggio e uno nel commento.

Possibili prblems:

  • Ci sono due messaggi fisici con lo stesso ID
  • Lo stesso messaggio è stato tirato su come un messaggio e un commento
  • Lo stesso messaggio viene tirato due volte in lo stesso contesto

Che il problema a volte scompare quando si riavvia, indica un problema con la pulizia del contesto. Stai usando le istruzioni "using".

Avete funzionalità per passare da un messaggio a un commento?

+0

No, non esiste tale funzionalità. per favore vedi modifica – Martin

2

Come si deduce, sembra che il contesto recuperi un commento come messaggio (non sapendo che si tratta di un commento). Successivamente, chiedi il commento effettivo, quindi il contesto recupera il commento. Ora ci sono due istanze di oggetto nel contesto con lo stesso ID: uno è un messaggio e uno è un commento.

Sembra che l'eccezione non venga lanciata fino a dopo che entrambi gli oggetti sono stati caricati (ovvero quando si tenta di accedere al Messaggio la seconda volta).Se riesci a trovare un modo per rimuovere il messaggio dal contesto quando viene caricato il commento, questo potrebbe risolvere il tuo problema.

Un'altra opzione potrebbe essere l'uso del modello Tabella per gerarchia. Ciò si traduce in un cattivo design del database, ma alla fine della giornata è necessario utilizzare ciò che funziona.

Potrebbe essere possibile evitare il problema assicurandosi che gli oggetti siano caricati come Commenti per primi. In questo modo, quando chiedi il messaggio, il contesto lo sa già.

Considerare inoltre l'utilizzo di Composition over Inheritance, in modo che un messaggio contenga 0..1 CommentDetails.

Il suggerimento finale è rimuovere la dipendenza da Entity Framework dal codice di controllo e creare un livello di accesso ai dati che fa riferimento all'EF e recupera gli oggetti. Il DAL può trasformare gli oggetti Entity Framework in un diverso insieme di oggetti Entity che sono più facili da usare nel codice. Questo approccio produrrà molti overhead di codice, ma potrebbe essere adatto se non è possibile utilizzare Entity Framework per produrre un modello Entity che rappresenta le Entità nel modo in cui si desidera lavorare con esse.

Per riassumere, a meno che MS non risolva questo problema, non esiste una soluzione al problema che non implichi un ripensamento del proprio approccio. Sfortunatamente il Entity Framework non è l'ideale, specialmente per i modelli Entity complessi: potresti stare meglio creando il tuo DAL e ignorando del tutto l'EF.