EF 4.1、POCO:データの更新を高速化するためにAutoDetectChanges(Configuration.AutoDetectChangesEnabled = false )をオフにしました。次に、エンティティの状態をEntityState.Modifiedに変更して、追加またはアタッチを実行します。これにより、データベースで更新されていない他のオブジェクトへの参照が発生します。ただし、すべてのスカラープロパティは正常に更新されます。
プロファイラーが示すEFは、すべてのスカラープロパティに対してSQL更新操作を生成しますが、参照型に対しては生成しませんが、コードでその値を実際に変更しました。この問題は、私のモデルのすべてのタイプのエンティティで再現されました。
操作を追加するか、 EntityStateでアタッチします。両方とも正常に機能します。AutoDetectChangesをオンに戻すと、更新されたレコードでも期待どおりにすべてが正常に機能します。
何が悪いのか理解するのを手伝ってください。EFのDetectChangesに関する優れた包括的なドキュメントが見つかりません。
アップデート
問題を再現するために、コードの例をいくつか示すように求められました。ドメイン:
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; }
}
DataContext:
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);
}
}
1つのレコードをClintテーブルに追加し、もう1つをアドレスに追加します。クライアントをアドレスにポイントします。次に、次のコードを実行します。
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に変更するか、特定の値に戻すか、または1つの具象値を他の具象値に戻すかは問題ではないことに注意してください。AutoDetectChanges= falseの間、変更は追跡されません。EFバグのようです。