EF Core Attach方法未更新关联实体的问题咨询
实体定义
public class Department { public int Id { get; set; } public string Name { get; set; } public IList<Employee> Employees { get; } = new List<Employee>(); } public class Employee { public int Id { get; set; } public string Name { get; set; } public string Designation { get; set; } public int DepartmentId { get; set; } public Department Department { get; set; } = null!; }
初始数据
初始Employee表包含两条记录:Id=1的员工Name为"Messi"、Designation为"Developer"、DepartmentId=1;Id=2的员工Name为"Sharapova"、Designation为"Manager"、DepartmentId=1。
执行的更新代码
context.Attach( new Department { Name = "Testing", Employees = { new Employee { Name = "Ronaldo", Designation = "MD", DepartmentId = 1 }, new Employee { Id = 2, Name = "Sharapova", Designation = "VP", DepartmentId = 1 } } }); context.SaveChanges();
异常现象
- Id为2的员工(Name="Sharapova"、Designation="VP"、DepartmentId=1)未被更新,Designation仍为"Manager"
- 新增的员工Ronaldo的DepartmentId被设为2,而非预期的1
问题原因分析
1. Id=2的员工未被更新的原因
调用Attach方法时,EF Core会把整个对象图标记为Unchanged状态。对于已设置Id的实体(这里的Id=2的Employee),EF Core默认认定它是数据库中已存在的记录,但因为状态是Unchanged,SaveChanges()执行时不会生成对应的更新SQL语句。
只有手动将实体状态改为Modified,或者使用Update方法、先查询实体再修改属性,EF Core才会识别到需要更新该记录。
2. 新增员工DepartmentId变为2的原因
你创建的Department对象未设置Id属性,EF Core会将其判定为新实体,执行SaveChanges()时会自动为它生成Id(此处生成了Id=2)。
由于Employee和Department是关联关系,EF Core会自动维护外键:新增的Ronaldo虽然手动设置了DepartmentId=1,但因为它被添加到了这个新Department的Employees集合中,EF Core会覆盖手动设置的外键值,将其改为新Department的Id(2)。
另外,Id=2的Employee虽然设置了DepartmentId=1,但同样因为被包含在新Department的集合里,EF Core会尝试修改它的DepartmentId为2,但由于该实体状态是Unchanged,所以这个修改不会同步到数据库。
内容的提问来源于stack exchange,提问作者yogihosting

