2013-03-21 13 views
9

Sto migrando da Linq-to-SQL a Entity Framework (4.4), usando Database First con un DbContext. Mi chiedo se il seguente comportamento è normale:Devo impostare manualmente le proprietà della chiave esterna quando cambio le associazioni?

using (var e = new AgendaEntities()) { 
    var store = e.Stores.First(); 
    var office = e.Offices.Create(); 
    office.Store = store; // Set association 
    Console.WriteLine(office.StoreID); // shows Guid.Empty, expected store.ID! 
} 

In L2S, impostando l'associazione Store ad un'entità sarebbe anche aggiornare la chiave StoreID. In EF, questo non sembra accadere. Questo indipendentemente dal fatto che le entità siano nuove o caricate dal contesto.

Quando I SaveChanges, si salva correttamente e il StoreID viene aggiornato in modo che corrisponda a office.ID, ma perché ciò accade solo dopo il salvataggio?

C'è qualcosa che mi manca, o sono ora in grado di mantenere sincronizzate le chiavi esterne manualmente?


Soluzione Edit: questo si chiama proprietà correzione, e utilizzato per essere fatto automaticamente i proxy generati. Tuttavia, con DbContext questo non è più il caso. Secondo this Connect issue, questo è di progettazione.

Ciao, Il modello DbContext in realtà non genera le classi che verranno utilizzati come proxy di rilevamento delle modifiche - solo proxy lazy loading (che non fare fix-up). Abbiamo preso questa decisione perché i proxy di monitoraggio delle modifiche sono complessi e hanno molte sfumature che possono essere molto confusionarie per gli sviluppatori. Se si desidera eseguire la correzione prima di SaveChanges, è possibile chiamare myContext.ChangeTracker.DetectChanges. ~ EF squadra

Un'alternativa è quella di chiamare DbContext.Entry(entity), che sarà sincronizzare l'entità. Questo è descritto in questo articolo: Relationships and Navigation Properties in "Sincronizzazione delle modifiche tra FK e proprietà di navigazione"

+0

È difficile capire che non più persone apprezzano questa soluzione. Nessuno sta lavorando con dbcontext in questo modo? – danihp

+0

Personalmente, ora imposto le chiavi manualmente ogni volta che cambio le associazioni. La correzione è stata piacevole, ma dopo un po 'di riflessione, non ha molto senso aspettarsi che i POCO lo facciano comunque. Qualsiasi operazione che cambierà le associazioni dovrebbe essere comunque astratta in qualche metodo del dominio, quindi alla fine non è così stridente come pensavo. –

+0

Sono entità 'cieche' tramite dbEntityValidations con tutte le mie regole aziendali per essere in grado di esporre entità al livello dell'interfaccia utente, almeno per entità 'semplici'. Mi occupo di entità correlate lazyloading con 'entry.related' ma approccio detectChanges. Grazie per il tuo post e la soluzione. – danihp

risposta

6

No. L'Entity Framework fa questo per te. Leggi Relationships and Navigation Properties per ulteriori informazioni.

Assegnando un nuovo oggetto a una proprietà di navigazione. Il seguente codice crea una relazione tra un corso e uno department. Se gli oggetti sono attaccati al contesto, il course è anche aggiunti alla raccolta department.Courses, e la corrispondente struttura chiave esterna sull'oggetto corso è impostato al valore proprietà chiave del department.

  • course.Department = department;

Ma, come si osserva, questo accade solo dopo aver chiamato SaveChanges o una delle altre azioni menzionate nella parte di "sincronizzazione delle modifiche tra le FKS e le proprietà di navigazione" del documento collegato sopra.

Se si utilizza entità POCO senza deleghe, è necessario assicurarsi che il metodo DetectChanges viene chiamato per sincronizzare i relativi oggetti nel contesto. Nota che le seguenti API automaticamente attivano una chiamata DetectChanges.

  • DbSet.Add
  • DbSet.Find
  • DbSet.Remove
  • DbSet.Local
  • DbContext.SaveChanges
  • DbSet.Attach
  • DbContext.GetValidationErrors
  • DbContext. Entry
  • DbChangeTracke r.Entries
  • L'esecuzione di una query LINQ contro un DbSet

Se questo non sta accadendo affatto, la mia ipotesi è che non si è correttamente definito StoreID come chiave esterna della proprietà di navigazione Store.

+1

Penso che quello che sta succedendo sia descritto in "Sincronizzazione delle modifiche tra gli FK e le proprietà di navigazione", nella parte inferiore dell'articolo che hai collegato. Chiamando 'e.Entry (office)' sincronizza gli ID. Tuttavia, nel debugger posso vedere che i proxy vengono creati, quindi * dovrebbe * funzionare ... –

+0

@IliaJerebtsov ahh corretto. Inizialmente ho letto male la tua domanda. Pensavo avessi detto che non stava succedendo affatto. –

+0

Grazie, ho capito, a quanto pare la mancanza di correzione è di progettazione nell'API DbContext. –

Problemi correlati