2011-10-21 7 views
8

próbuję zaktualizować obiekt, który już wcześniej zapisany z EntityFramework 4.1 (CodeFirst)Aktualizowanie odwołanie do obiektu podrzędnego w Entity Framework 4.1 (CodeFirst)

Klasa Praca ma następujące właściwości ...

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; } 
} 

początkowy tworzyć działa dobrze, ale aktualizacja popełnia tylko zmiany strun ..

Jeśli zmienię obiekty podrzędne np JobType obiekt z JobTypeA do JobTypeB - T zmienił się nie jest zobowiązany ...

Nie szukam zmiany w JobType - tylko Job.

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

zaglądając do SQL Profiler - identyfikatory nie są jeszcze wysyłane do aktualizacji - jednak są one na początkowym wkładem!

Odpowiedz

15

Ustawienie stanu na Modified powoduje jedynie aktualizację właściwości skalarnych i złożonych, a nie właściwości nawigacyjnych. Wynika to tylko z wykrywania zmian w Entity Framework. Oznacza to, że trzeba załadować oryginał z bazy danych:

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(); 
} 

prawdopodobnie można by było również zwiększenie rozpoznawalności jakieś „sztuczki” w przypadku:

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(); 
} 

to nie zadziała jednak, jeśli chcesz ustaw JobType na null.

Jest to typowa sytuacja, która jest coraz znacznie prostsze, jeśli narazić kluczy obcych jako właściwości w modelu: Z JobTypeId w swojej jednostce Job Twój kod będzie działać, ponieważ nieruchomość FK jest skalarne i ustawiając stan na Modified także oznaczyć tę właściwość jako zmodyfikowaną.

+0

"Jest to typowa sytuacja, która staje się znacznie prostsza, jeśli ujawnisz klucze obce jako właściwości w swoim modelu" THIS. To powinno być zawarte w każdym samouczku EF. To niewiarygodne, jak to sprawia, że ​​rzeczy "po prostu działają". –

+0

@EugenTimm Jak to działa, gdy aktualizujesz odłączone? Czy aktualizujesz właściwość nawigacji lub FK? –