7

Ho questo codice in un servizio di Windows mirato a .Net 4.5 che utilizza un database-primo strato Entity Framework:Perché Entity Framework inserisce figli quando aggiorno il genitore?

var existingState = DataProcessor.GetProcessState(workerId); 

existingState.ProcessStatusTypeId = (int)status; 
existingState.PercentProgress = percentProgress; 
existingState.ProgressLog = log; 

DataProcessor.UpdateProcessState(existingState); 

E questo codice in una classe di elaborazione dei dati nella stessa soluzione:

public ProcessState GetProcessState(int id) 
{ 
    using (var context = new TaskManagerEntities()) 
    { 
     var processes = (from p in context.ProcessStates.Include("ProcessType").Include("ProcessStatusType") 
         where p.IsActive && p.ProcessStateId == id 
         select p); 

     return processes.FirstOrDefault(); 
    } 
} 

public ProcessState UpdateProcessState(ProcessState processState) 
{ 
    using (var context = new TaskManagerEntities()) 
    { 
     context.ProcessStates.Add(processState); 
     context.Entry(processState).State = System.Data.EntityState.Modified; 
     context.SaveChanges(); 
    } 

    return processState; 
} 

ProcessState è un padre di altre due classi, ProcessStatusType e ProcessType. Quando eseguo quel codice nel servizio Windows, recupera un record, aggiorna l'entità e la salva. Nonostante il figlio ProcessType non sia mai usato nel codice precedente, quando viene eseguito il salvataggio sull'entità ProcessState, EF inserisce un inserto nella tabella ProcessType e crea un nuovo record al suo interno. Quindi modifica l'FK nell'entità ProcessStatus per puntarla sul nuovo figlio e salvarla nel database.

Non Non fare questo nella tabella ProcessStatusType, che è impostato con un sostanzialmente identico FK relazione padre-figlio.

Ora ho un database pieno di voci ProcessType identiche di cui non ho bisogno e non so perché questo si sta verificando. Sento che sto facendo un errore evidente che non riesco a vedere perché questo è il mio primo progetto EF. Il problema è che sto permettendo che il contesto scada tra una chiamata e l'altra ma mantenendo la stessa entità?

+1

Verificare che l'oggetto ProcessType da caricare abbia la proprietà per la chiave primaria della tabella e che sia stato compilato correttamente. Se per esempio,'ProcessType.Id = 0 ', EF penserà che si tratta di un nuovo oggetto e lo inserirà –

+0

Ho appena controllato, e lo fa. La chiave primaria è presente e corretta in entrata, ed è impostata sulla chiave primaria del nuovo record del database quando esce. – RedBrogdon

risposta

5

L'utilizzo di Aggiungi imposta lo stato di tutti gli elementi su Aggiunto, causando l'inserimento degli elementi secondari. L'elemento padre non viene inserito quando si specifica EntityState.Modified per questo elemento.

Provare a utilizzare quanto segue in UpdateProcessState piuttosto che utilizzare Aggiungi.

context.ProcessStates.Attach(processState); 
context.Entry(processState).State = EntityState.Modified; 
context.SaveChanges(); 

Fissare imposterà lo stato di tutti gli elementi a Invariato e specificando modificato per l'elemento genitore si indica che solo questo elemento dovrebbe essere aggiornato.

Su un'altra nota. È necessario utilizzare lo standard fortemente Include(x => x.ProcessType) anziché Include("ProcessType").

+0

Grazie per l'aiuto. Il problema Attach/Add stava causando il problema. Ho apportato questo cambiamento e tutto funziona correttamente ora. Per quanto riguarda le affermazioni di inclusione fortemente tipizzate, quelle sono ancora disponibili in EF5? Il mio compilatore genera un errore e ho visto questo post: http://stackoverflow.com/questions/4544756/using-include-in-entity-framework-4-with-lambda-expressions che sembra indicare che sono deprecato. – RedBrogdon

+1

Sì, l'inclusione fortemente tipizzata è supportata, http://msdn.microsoft.com/en-us/library/gg671236(VS.103).aspx. Prova ad aggiungere un utilizzo per System.Data.Entity per impedire al compilatore di lamentarsi. – Martin4ndersen

+0

Ed eccoli qui. Grazie ancora. Interessante che Intellisense suggerirà di usare "istruzioni" per metodi di assemblaggio non segnalati ma disponibili in un riferimento, ma non se si tratta di polimorfi di qualcosa già presente negli spazi dei nomi. – RedBrogdon

Problemi correlati