3

英語が下手でごめんなさい-WPF(.net 4.5)アプリケーションでEF 5(Code First)を使用しています。各ウィンドウには独自のコンテキストがあります。

私はこのようなモデルを持っています(簡潔にするためにコードは省略されています):

public class Car
{
  public string Model { get; set; }  
  public int BrandId { get; set; }  
  public virtual Brand Brand { get; set; }
}

コンボボックスを使用して、ユーザーがをに関連付けることができるようにしBrandますCar。問題は、を保存するたびにCar、複製された新しいBrandものも保存されることです。これは、コンボボックスに。をロードしたために発生しますAsNoTracking()

ここで、他のDbContextインスタンスで行われAsNoTracking()たテーブルへの変更のロードに問題があったため(を使用して)コンボボックスをロードします。BrandmyContext.Set<Brand>().Load()

だから私の質問は、これをどのように解決するのですか?(を使用せずに)コレクションを強制的にリロードする別の方法がある場合はAsNoTracking、それが便利です。AsNoTrackingさらに良いのは、ロードされたエンティティが新しいものではないことをEFに通知できることです。

編集1: @Mark:ありがとう、エンティティをコンテキストにアタッチすることでうまくいきました。しかし、私は検証を行い、すべてのフォームのデータを保存する汎用基本クラスを使用しているため、エンティティを手動でアタッチすることはあまり実用的ではありません...あなたの提案に基づいて、Carエンティティを追加した後、保存する前にこれを行うことになりました:

var entities = (((IObjectContextAdapter)ctx).ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added));

foreach (var item in entities)
{
    if ((item.Entity as EntityBase).Id > 0)
    {
        item.ObjectStateManager.ChangeObjectState(item.Entity, EntityState.Unchanged);
    }
}

(私のエンティティはすべてEntityBaseから継承し、すべてのキーはデータベースで生成されます)。これはうまくいきましたが、セカンドオピニオンが欲しいです...これは良いですか、それとももっと簡単な方法がありますか?

4

1 に答える 1

3

何が起こっているのかというと、あなたのコンテキストは車に付けられているブランドを認識していないので、外部キーに一致する新しいブランドを作成しています。保存する前に、ブランドをコンテキストに添付する必要があります。

context.Brands.Attach(brand);

個別にリロードすることにより、保存する前に個々のブランドをリロードできます。

db.Entry(brand).Reload();

車を保存するときにブランドへの変更を実際に保持したくない場合はブランドが変更されていないことをコンテキストに伝え、更新を防ぐことができます。

context.Entry(brand).State = EntityState.Unchanged;
于 2012-08-29T19:35:21.913 に答える