假设我们有一个Person类(具有Id和Age的属性),假设我们需要将ID为1的人的Age从29更改为30,
Person p = new Person(){ Id = 1 } //Age is default to 0 here, but does't matter, because it is going to be changed later
var entity = context.Persons.Attach(p);
p.Age = 30;
Console.WriteLine("entity state:" + entity.State);
foreach (var modifiedProperty in entity.Properties.Where(p => p.IsModified))
{
Console.Write($"The {modifiedProperty.Metadata.Name} property is marked as modified");
}
context.SaveChanges();
,输出显示:
entity.State
已未更改,并且未将任何属性标记为已修改,但是EF内核仍然生成了一个更新SQL来设置[年龄] = 30, '很困惑,如果实体状态保持不变并且EF核心认为没有属性修改,那么EF核心不应该生成更新SQL吗?
如果我使用Update()方法而不是Attach()
...
var entity = context.Persons.Update(p);
...
然后一切正常,实体状态已修改,年龄被标识为已修改属性?
答案 0 :(得分:2)
调用context.ChangeTracker.DetectChanges()
时,实体的状态不会立即更新,而是会重新计算。
属性context.ChangeTracker.AutoDetectChangesEnabled
默认设置为true。这意味着在调用context.SaveChanges()
时,将首先自动调用context.ChangeTracker.DetectChanges()
,然后更新实体的状态。
根据文档https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbset-1.update?view=efcore-2.1,实体对象的所有属性都将由update方法本身以Modified
状态标记,无论该属性值是否被真正修改。因此,Update
方法不是使用检测EF的更改功能,而是强行设置实体的状态。