7

我有这样的代码在Windows服务针对.NET 4.5使用数据库,第一实体框架层:当我更新父项时,为什么实体框架会插入子项?

var existingState = DataProcessor.GetProcessState(workerId); 

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

DataProcessor.UpdateProcessState(existingState); 

而这种代码在数据处理类在同一个解决方案:

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是另外两个类ProcessStatusType和ProcessType的父类。当我在Windows服务中运行该代码时,它将检索记录,更新实体并将其保存。尽管在上面的代码中永远不会使用ProcessType子类,但在执行ProcessState实体保存时,EF会在ProcessType表上执行插入操作并在其中创建新记录。然后它更改ProcessStatus实体中的FK,将其指向新的子节点并将其保存到数据库。

它确实不是在ProcessStatusType表中执行此操作,该表使用基本上相同的FK父子关系进行设置。

我现在有一个数据库完全相同的ProcessType条目,我不需要,我不知道这是为什么发生。我觉得我犯了一些我看不见的明显错误,因为这是我的第一个EF项目。我允许上下文在呼叫之间过期但维护同一实体的问题是否存在?

+1

检查以确保您正在加载的ProcessType对象具有其表的主键的属性并且它已正确填充。例如,如果'ProcessType.Id = 0',EF会认为它是一个新对象,并插入它 – 2013-02-15 21:15:53

+0

我刚刚检查过,它确实如此。主键存在且正在进行中,并且在新数据库记录出现时被设置为主键。 – RedBrogdon 2013-02-15 21:22:56

回答

5

使用Add将所有元素的状态设置为Added,这会导致子元素被插入。当您为此元素指定EntityState.Modified时,不插入父元素。

尝试在UpdateProcessState中使用以下内容,而不是使用Add。

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

附加将设置所有元素不变和通过的状态确定为修改父元素要表示只有这个元件应该被更新。

另一个说明。您应该使用强类型的Include(x => x.ProcessType)而不是Include("ProcessType")

+0

感谢您的帮助。附加/添加问题导致了问题。我做了这个改变,现在一切正常。关于强类型的包含语句,那些仍然可以在EF5中使用的语句?我的编译器在他们抛出一个错误,我看到这个帖子:http://stackoverflow.com/questions/4544756/using-include-in-entity-framework-4-with-lambda-expressions这似乎表明他们是弃用。 – RedBrogdon 2013-02-15 21:54:00

+1

是的,支持强类型的Include,http://msdn.microsoft.com/en-us/library/gg671236(VS.103).aspx。尝试添加一个使用System.Data.Entity,使编译器停止抱怨。 – Martin4ndersen 2013-02-15 21:59:07

+0

他们在那里。再次感谢。有趣的是,Intellisense会建议将“使用”语句用于未引用但可用的引用程序集方法,但是如果它们是已经存在于命名空间中的东西的多态性,则不会。 – RedBrogdon 2013-02-15 22:06:12

相关问题