2011-10-21 15 views
8

Sto cercando di aggiornare un oggetto che ho salvato in precedenza con EntityFramework 4.1 (CodeFirst)Aggiornamento di un riferimento a un oggetto figlio in Entity Framework 4.1 (CodeFirst)

Il lavoro di classe ha le seguenti proprietà ...

public class Job 
{ 
    [key] 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public Project Project { get; set; } 
    public JobType JobType { get; set; } 
    public string Description { get; set; } 
} 

l'iniziale creare lavori bene, ma l'aggiornamento impegna unicamente modifiche alle corde ..

Se cambio gli oggetti figlio ad esempio, la proprietà JobType da JobTypeA a JobTypeB - t il cambio non è stato commesso ...

Non sto cercando di passare a JobType - solo a Job.

using (var context = new JobContext()) 
{ 
    context.Jobs.Attach(job); 
    context.Entry(job).State = EntityState.Modified; 
    context.SaveChanges(); 
} 

Avere uno sguardo a SQL Profiler - gli ID non sono nemmeno di essere inviato per l'aggiornamento - tuttavia sono per l'inserto iniziale!

risposta

15

L'impostazione dello stato su Modified aggiorna solo le proprietà scalari e complesse, non le proprietà di navigazione. Questo avviene solo attraverso il rilevamento delle modifiche di Entity Framework. Ciò significa che è necessario caricare l'originale dal database:

using (var context = new JobContext()) 
{ 
    var originalJob = context.Jobs.Include(j => j.JobType) 
     .Single(j => j.Id == job.Id); 

    // Update scalar/complex properties 
    context.Entry(originalJob).CurrentValues.SetValues(job); 

    // Update reference 
    originalJob.JobType = job.JobType; 

    context.SaveChanges(); 
} 

Si potrebbe forse anche sfruttare alcuni "trucchi" nel tuo caso:

using (var context = new JobContext()) 
{ 
    var jobType = job.JobType; 
    job.JobType = null; 

    context.JobTypes.Attach(jobType); 
    context.Jobs.Attach(job); 
    // change detection starts from here, 
    // EF "thinks" now, original is JobType==null 

    job.JobType = jobType; 
    // change detection will recognize this as a change 
    // and send an UPDATE to the DB 

    context.Entry(job).State = EntityState.Modified; // for scalar/complex props 

    context.SaveChanges(); 
} 

Non funzionerebbe anche se si desidera impostare JobType a null.

Si tratta di una tipica situazione che sta diventando molto più semplice se si espone chiavi esterne come proprietà nel modello: Con un JobTypeId nella vostra Job entità il codice avrebbe funzionato perché la proprietà FK è scalare e impostare lo stato di Modified anche contrassegna questa proprietà come modificata.

+0

"Questa è una situazione tipica che sta diventando molto più semplice se si espongono chiavi esterne come proprietà nel modello" THIS. Questo dovrebbe essere incluso in ogni EF-tutorial. Non è credibile come le cose "funzionano". –

+0

@EugenTimm Come funziona quando si aggiorna un distaccato? Aggiorna la proprietà di navigazione o l'FK? –

Problemi correlati