7

Ho lavorato alla mia applicazione ASP.NET MVC da mesi. Quando ho iniziato a lavorare su di esso stavo usando Entity Framework 4.3 (Code-First w/Migrations). Mentre lo facevo, mi sono imbattuto in alcuni problemi nel tentativo di fare aggiornamenti sulla mia tabella MainClient. MainClient contiene tutte le informazioni di base di un client e ha una relazione 1: 1 con la tabella BPClient, che contiene informazioni più specifiche su tale client relative al loro accordo di licenza per il modulo BP. Entrambi possono essere modificati sulla stessa pagina in un controllo a schede. Tuttavia, ho continuato a ottenere la seguente eccezione quando si tenta di cambiare l'EntityState dell'oggetto MainClient ad essere EntityState.Modified:Entity Framework 4.3 e 5.0 Aggiornamento differenze

System.InvalidOperationException : An object with the same key already exists 
in the ObjectStateManager. The ObjectStateManager cannot track multiple objects 
with the same key. 

ho notato durante il debug che l'oggetto stesso è stato considerato indipendente quando è andato nella mia classe Controller essere salvato. Come soluzione alternativa a questo problema, ho applicato una soluzione simile ai problemi rilevati in this blog post e in this SO question. Ecco come il codice per ri-fissare gli oggetti sembrava dopo (disordinato, lo so), dato il metodo Edit viene passata in un oggetto MainClient chiamato client:

var newClientObject = new MainClient { ClientID = client.ClientID }; 
Db.MainClients.Attach(newClientObject); 
Db.Entry(newClientObject).CurrentValues.SetValues(client); 

var bpClient = new BPClient { ClientID = client.ClientID, BaseClient = newClientObject }; 
if (client.BPClient != null) 
{ 
    Db.BostonpostClients.Attach(bpClient); 
    Db.Entry(bpClient).CurrentValues.SetValues(client.BPClient); 
} 

Db.SaveChanges() 

questo ha funzionato bene e dandy attraverso tutti i casi di test. Fino a poco tempo fa.

Recentemente, ho aggiornato la mia applicazione per utilizzare Entity Framework 5 (utilizzando ancora Code-First). Quando stavo testando di nuovo la pagina di modifica di MainClient, però, ho trovato un comportamento piuttosto irregolare. Alcuni campi, se modificati, verrebbero salvati senza problemi. Altri non sarebbero mai stati assegnati al DB. Altri ancora continuerebbero bene, ma solo se fossero l'unica parte dell'oggetto che è stato modificato. Ho eseguito il debugging del DbContext che si trovava nella classe Controller e ho scoperto, piuttosto fastidiosamente, che non solo le modifiche apportate alla pagina venivano inviate alla classe Controller, ma che ObjectStateManager aveva sia gli oggetti MainClient che BPClient in it con le modifiche che sono state fatte anche sulla pagina! Vorrei comunque ricordare che non ho ricevuto un errore durante il debug, nemmeno dopo SaveChanges().

ho deciso di provare a ripristinare il codice per quello che era stato in origine, vale a dire il modo logico di farlo:

Db.Entry<BPClient>(client.BPClient).State = EntityState.Modified; 
Db.Entry<MainClient>(client).State = EntityState.Modified; 

Db.SaveChanges(); 

E ora funziona tutto bene. No InvalidOperationException. Quindi è stato risolto bene.

Ciò che mi dà ancora fastidio è cercare di capire solo cosa è cambiato in 5.0 che ha reso la mia correzione precedente smettere di funzionare e andare su tutte le furie. Perché quel codice funziona bene in 4.3 ma non in 5.0? Cosa in 5.0 reso commettendo sul database con quel codice così irregolare?

Qualcuno sa perché questo sarebbe successo?

+0

Potrebbe essere di aiuto. Entity Framework 5 Enums and Moving Solution di EF 4.3 http://thedatafarm.com/blog/data-access/video-entity-framework-5-enums-and-moving-solution-from-ef-4-3/ – Aru

risposta

0

Ho avuto questo problema me stesso. Stavo usando le classi IDbSet per popolare le tabelle del database, quello che ho trovato è stato quando ho creato una proprietà virtuale EF5 esegue un carico pigro (le mie proprietà virtuali in cui altri oggetti nel database). Ciò significa che ricevo una nuova chiave primaria per la proprietà virtuale. Bene, se non ho un ID specifico associato all'oggetto che voglio fare riferimento a EF 5, cerco di creare una relazione a due vie. Se non specifichi esplicitamente a EF quale proprietà mappare in DBContext, imposta due chiavi esterne allo stesso oggetto che non è consentito. Spero che questo ti aiuti.

+0

Grazie per aver cercato di rispondere alla mia domanda. Non penso che questo sia il caso qui, però.Ho già impostato 1: 1 tra MainClient e BPClient come una relazione a due vie (sia con proprietà virtuali che con ID). Sto solo cercando di capire perché il codice all'improvviso ha smesso di funzionare. – IronMan84

+0

utilizzando solo le proprietà virutali provoca il caricamento lazy, hai la stessa mappa fatta nel tuo dbcontext tra le proprietà? – Robert

+0

Sto utilizzando Data Annotation, non l'API FLuent. Il mapping è interamente sull'oggetto stesso, non nel DbContext. È accaduto qualcosa tra 4.3 e 5.0 per quanto riguarda il caricamento pigro che avrebbe influenzato il codice in questo modo? – IronMan84

Problemi correlati