Why does the Entity Framework insert children when updating a parent?

I have this code in a windows service destined for .Net 4.5 which uses the first level of the Entity Framework based on the database:

var existingState = DataProcessor.GetProcessState(workerId); existingState.ProcessStatusTypeId = (int)status; existingState.PercentProgress = percentProgress; existingState.ProgressLog = log; DataProcessor.UpdateProcessState(existingState); 

And this code in the data processing class in the same solution:

 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 is the parent of two other classes: ProcessStatusType and ProcessType. When I run this code on a Windows service, it retrieves the record, updates the object, and saves it. Although the ProcessType child is never used in the above code, when a ProcessState is saved, EF inserts into the ProcessType table and creates a new record in it. It then modifies the FK in the ProcessStatus object to point it to a new child and stores it in the database.

This is not done in the ProcessStatusType table, which is configured with essentially identical FK parent-child relationships.

Now I have a database full of identical ProcessType entries that I don’t need, and I don’t know why this is happening. I feel like I am making an obvious mistake that I do not see, because this is my first EF project. Is the problem that I allow the context to expire between calls, but supporting the same object?

+7
source share
1 answer

Using Add, the state of all elements in the Added is added, which causes the inclusion of child elements. The parent element is not inserted because you are specifying EntityState.Modified for this element.

Try using the following in UpdateProcessState instead of using Add.

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

Attach will set the state of all elements to Unchanged, and by specifying Modified for the parent element, you indicate that only this element is updated.

In another note. You should use a strongly typed Include(x => x.ProcessType) , not Include("ProcessType") .

+5
source

All Articles