2011-08-16 10 views
1

EF 4.1、POCO:私はデータの更新を高速化するAutoDetectChangesConfiguration.AutoDetectChangesEnabled =偽)をオフ。次に、私はを追加します。またはを添付します。を添付し、エンティティの状態をEntityState.Modifiedに変更します。このため、データベース内の他のオブジェクトへの参照が更新されません。ただし、すべてのスカラープロパティは正常に更新されます。EF 4.1、POCO:リファレンス・タイプのプロパティがケースAutoDetectChangesで更新されていない=偽

Profilerが示すように、EFはすべてのスカラープロパティに対してSQL更新操作を生成しますが、参照型は生成しませんが、実際にはコード内の値を変更しました。この問題は、モデルのすべてのタイプのエンティティで再現されました。

操作を追加するか では両方の作業罰金EntityState.Added取り付けます。 AutoDetectChangesをオンにすると、更新されたレコードに対してもすべて正常に動作します。

何が問題なのか理解してください。私はEFのDetect Changesに関する包括的な文書を見つけることができません。

UPDATE

私は問題を再現するために、コードのいくつかの例を置くように頼まれました。ドメイン:

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); 
    } 
} 

クリントテーブルとAddressへの1に1件のレコードを追加します。ポイントクライアントをアドレスに転送します。大丈夫、すべてtrueにAutoDetectChangesEnabled

update [dbo].[Clients] set [Name] = 'Anna' 
where ([Id] = 1) 

セットと、再び今回のコードを実行します:

update [dbo].[Clients] 
set [Name] = 'Anna', [Address_Id] = null 
where (([Id] = 1) and [Address_Id]=1) 
をこのコードは次のようにSQLスクリプトを生成しない

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(); 
} 

:その後、次のコードを実行します。

Addressの値を特定の値からヌルに変更したり、特定の値に戻したり、具体的な値を他の具体的な値に変更したりすると、AutoDe tectChanges = false。 EFバグのようです。私は間違いなくそれを好きではないしかし

cntx.Entry(client).Reference(c => c.Address).CurrentValue = null; 

+0

問題を再現できるいくつかのコードを表示してください。 –

答えて

2

まあを参照してください、私も偽AutoDetectChangesEnabled =と連携リファレンスプロパティ値を設定する方法を見つけました。 1)コードが醜い。 2)私の場合ではなく、動作させるためにコンテキストにアクセスする必要があります。このプロパティは、DbContextにしかアクセスできないリポジトリの外部に設定したいと思います。プロパティ値が変更されたことをEFに知らせる他の簡単な方法はありますか?

を更新しました。これでわかりやすい回避策が見つかりました。単にcntx.ChangeTrackerを実行してください。cntx.SaveChanges()を実行する前にDetectChanges()を呼び出してください。 EFが正しいSQLアップデートスクリプトを生成するのに役立ちます

+0

あなたの更新された回答は、私が提供したものです.BTW ... –

+0

それは私があなたの答えをupvoted理由です。まだEFがなぜ変わったのか理解していません。 AutoDetectChangesEnabledをオフにすると、EFはスカラ型のプロパティの変更を追跡しますが、参照型は変更しません。それはまったく動作しないか、すべてのプロパティで動作するはずです。それ以外の場合は混乱の原因になります。私はそれをMicrosoftのバグと見なします。 – YMC

2
+0

包括的なドキュメントではありません。スナップショットやプロキシ検出手法を使用する場合など、このDetect Changesの実装について多くの質問が残されています。また、EFが参照プロパティの更新をスキップした場合のこの動作について説明します。 – YMC

関連する問題