EF 4.1,POCO:我关闭了AutoDetectChanges ( Configuration.AutoDetectChangesEnabled = false ) 以加快数据更新。然后我运行Add or Attach并将实体状态更改为EntityState.Modified。所有这些都会导致对其他对象的引用未在数据库中更新。但是,所有标量属性都已成功更新。
Profiler 显示 EF 为每个标量属性生成 SQL 更新操作,但不是为引用类型生成 SQL 更新操作,尽管我确实在我的代码中更改了它的值。此问题针对我模型中的每种类型的实体进行了重现。
添加操作或Attach with EntityState.Added都可以正常工作。如果我重新打开AutoDetectChanges,对于更新的记录,一切都会按预期正常工作。
请帮助我找出问题所在。我找不到任何关于 EF 的 Detect Changes 的全面文档。
更新
我被要求提供一些代码示例来重现该问题。领域:
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public virtual string City { get; set; }
}
数据上下文:
public class DataContext : DbContext
{
public DbSet<Client> Clients { get; set; }
public DbSet<Address> Address { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Client>().HasOptional(c => c.Address);
}
}
将一条记录添加到 Clint 表,并将一条记录添加到 Address。将客户端指向地址。然后运行以下代码:
using (var cntx = new DataContext())
{
cntx.Configuration.AutoDetectChangesEnabled = false; // Reason of problem
var client = cntx.Clients.First();
client.Name = "Anna"; // This property will be updated
client.Address = null; // This property will not be updated
cntx.Clients.Attach(client);
cntx.Entry(client).State = EntityState.Modified;
cntx.SaveChanges();
}
此代码确实会生成如下 SQL 脚本:
update [dbo].[Clients] set [Name] = 'Anna'
where ([Id] = 1)
将 AutoDetectChangesEnabled 设置为 true 并再次运行代码,这次一切正常:
update [dbo].[Clients]
set [Name] = 'Anna', [Address_Id] = null
where (([Id] = 1) and [Address_Id]=1)
请注意,如果您将 Address 的值从特定值更改为 null,或者返回特定值,或者将一个具体值更改为另一个具体值,则在 AutoDetectChanges=false 时不会跟踪任何更改。似乎是 EF 错误。