Quindi sono nuovo di EF (sto usando EF6) e ho problemi a capire il concetto, sto cercando di aggiornare l'entità con la raccolta figlio.
Ecco la mia classe di entità:
public class TimeSheet
{
public int TimeSheetID { get; set; }
public virtual ICollection<TimeSheetDetail> Details { get; set; }
}
public class TimeSheetDetail
{
public int TimeSheetDetailID { get; set; }
public int TimeSheetID { get; set; }
public virtual TimeSheet TimeSheet { get; set; }
}
Il mio metodo di aggiornamento:
public void Update(TimeSheet obj)
{
var objFromDB = Get(obj.TimeSheetID);
var deletedDetails = objFromDB.Details.Except(obj.Details).ToList();
_dbContext.Entry(obj).State = EntityState.Modified;
//track if details exist
foreach (var details in obj.Details)
{
_dbContext.Entry(details).State = details.TimeSheetDetailID == 0 ? EntityState.Added : EntityState.Modified;
}
//track deleted item
foreach (var deleted in deletedDetails)
{
_dbContext.Entry(deleted).State = EntityState.Deleted;
}
}
public TimeSheet Get(object id)
{
//return _timeSheet.Find(id); //Without AsNoTracking I got error
int x = Convert.ToInt32(id);
return _timeSheet.AsNoTracking().SingleOrDefault(a => a.TimeSheetID == x);
}
Sopra codice dammi Attaching an entity of type 'ClassName' failed because another entity of the same type already has the same primary key value
. Quindi la mia domanda è:
Come aggiorni la collezione dei bambini con EF? Significa che ho bisogno di aggiungere nuovo se non esiste nel DB, aggiornare altrimenti o eliminare dal DB se è stato rimosso nel POST
.
Se non utilizzo AsNoTracking()
, verrà AsNoTracking()
Saving or accepting changes failed because more than one entity of type 'ClassName' have the same primary key value
. Ho notato che l'errore è stato causato dal mio DbSet
aggiunge i dati dal DB alla sua proprietà Local
se non utilizzo AsNoTracking()
che fa sì che il framework EF lanci l'errore perché pensa che io abbia dati duplicati. Come funziona davvero?
Come puoi vedere sto cercando di confrontare objFromDb
con obj
per verificare se l'utente rimuove uno dei dettagli così posso rimuoverlo dal database. Invece ho ottenuto un sacco di DynamicProxies
dal risultato della raccolta. Che cos'è DynamicProxies
e come funziona?
C'è qualche buon articolo o 101 tutorial su EF? Finora ne ho visto solo uno semplice che non aiuta il mio caso e mi sono guardato attorno e ho trovato una risposta mista su come fare cose. Per essere onesti, a questo punto vorrei andare con il classico ADO.Net invece di EF.
Per una migliore comprensione del framework di entità, pensare a DbContext
come proxy tra l'applicazione e il database. DbContext
memorizzerà tutto nella cache e userà ogni bit di dati dai valori memorizzati nella cache a meno che tu non gli dica di non farlo.
Per 1 .: Questo dipende dall'ambiente in cui DbContext
non è disposto tra la selezione e l'aggiornamento delle entrate, basta semplicemente chiamare SaveChanges
ei dati verranno salvati. Se DbContext
è disposto, è possibile scollegare le entiti dal contesto, modificare i dati, ricollegarli e impostare EntityState
da modificare.
Non posso darti una risposta sicura al 100%, perché ho smesso di usare il framework delle entità circa sei mesi fa. Ma so che è un dolore aggiornare relazioni complesse.
Per 2 .: Il comando AsNoTracking
dice AsNoTracking
non tracciare le modifiche apportate alle entità all'interno di questa query. Ad esempio, seleziona 5 TimeSheets dal tuo Database, modifica alcuni valori nella prima entità ed elimina l'ultimo. DbContext
sa che la prima entità viene cambiata e l'ultima viene cancellata, se chiami SaveChanges
il DbContext
aggiornerà automaticamente la prima entità, eliminerà l'ultima e DbContext
manterrà le altre intatte. Ora provate ad aggiornare un'entità da soli e collegate nuovamente la prima entità a DbContext.
DbContext ora avrà due entrate con la stessa chiave e questo porta alla tua eccezione.
Per 3 .: DynamicProxies
è l'oggetto utilizzato dal framework entità per tenere traccia delle modifiche di tali entità.
Per 4 .: Controlla questo link , inoltre c'è un buon libro sull'entità framework 6 (Titolo: "Programming Entity Framework")