2011-12-08 25 views
8

私はMVCプロジェクトを持ち、データベースにEntity Framework Code FirstとPOCOオブジェクトを使用しています。例:Entity Frameworkで関連するエンティティを更新する方法

public class ClassA 
{ 
    public int? Id {get; set;} 
    public string Name { get; set;} 
    public virtual ClassB B {get; set;} 
} 

public class ClassB 
{ 
    public int? Id {get;set;} 
    public string Description {get;set;} 
} 

モデルを作成または編集するActionResultがあります。問題は、このActionResultを呼び出してモデルを更新し、model.Bが変更された場合、その関係はデータベースに保存されません。新しいオブジェクトを作成するためにActionResultが呼び出されると、期待どおりに動作します。これをどうすれば解決できますか?

public ActionResult Save(ClassA model) 
{ 
    model.B = GetBFromDb(model.B.Id.Value); 

    if(ModelState.IsValid) 
    { 
    if (id.HasValue) 
    { 
     context.Entry(model).State = System.Data.EntityState.Modified; 
    } 
    else 
    { 
     context.ClassAs.Add(model); 
    } 
    context.SaveChanges(); 
    // redirect to index etc. 
    } 
    return View("EditForm", model); 
} 

答えて

3

私は、ClassBへの外部キーでClassAを変更することによってそれを解決そしてBIdの値を設定:

public class ClassA 
{ 
    public int? Id {get; set;} 
    public string Name { get; set;} 
    public int BId {get;set;} // foreign key to B 
    public virtual ClassB B {get; set;} 
} 

なぜ、この外部キープロパティは、EFの生成外国KYの代わりに仕事をしていますか?

+3

EFで回避できないギャップと余分なコードを証明する必要があります。さもなければ、それは関係を見ることができません。 FKプロパティではスカラー値であり、EFが複数のプロセス間を追跡するのが簡単です。私は実際にこの正確なトピックについて私の2012年1月Data Pointsコラムを書いた! EFは、FKスカラープロパティを持つときに使用するほうがはるかに簡単です。そうでなければ、 "仕事をする"と期待している多くの機能は、何が起こっているのか、必要な情報をどのように提供するのかをより深く理解することができません。申し訳ありませんが、 –

+0

の前に行方不明のFKが表示されませんでした.JulieLerman、問題ありません、あなたの助けをありがとう! :) – Marthijn

2

あなたは、単に呼び出すことはできません。

context.Entry(model).State = System.Data.EntityState.Modified; 

実体がEFがそれを追跡を開始できるようにするために、最初のコンテキストから取得する必要があります。次に、context.SaveChanges()を呼び出す前に、そのエンティティに変更を適用する必要があります。

var entity = context.ClassAs.Find(model.Id); 

// set properties you want to modify on entity 
entity.Name = model.Name; 
entity.ClassB = context.ClassBs.Find(model.ClassB.Id); 
// other changes to entity as required... 

context.SaveChanges(); 

このようにして、EFはentityを追跡し、それに対して更新を適用することを知っています。

+0

ありがとうございます!そして、どのように 'entity.ClassB = null;'を設定するのですか? nullに設定するだけではうまくいかないようです。 – Marthijn

+1

Yuck ... context.Entry(model).Stateは、モデルが追跡されているかどうかをコンテキストに見させ、そうでなければ追跡を開始します。モデルインスタンスを追跡するために別のdbクエリを実行する必要はありません。 Henkieがその問題に取り組んでいる問題は、Entryメソッドが渡されたエンティティの状態を変更するだけであるということです。変更された状態の設定は、グラフの残りの部分には適用されません。 –

+0

@JulieLermanありがとう、私はまた、状態をModifiedに設定するいくつかのチュートリアルを見つけました。しかし、私はまだ関係が更新されないという問題があります。 – Marthijn

0

添付して状態を変更したエンティティフレームワークに設定すると、更新用のすべてのプロパティが送信されます。ここでは、別々の負荷が発生するように、以下ではオッターのアプローチをとる必要はありません。このようにすれば、モデルを渡す際には意味がありません。idだけを指定してから、TryUpdateModelを呼び出してフォームからプロパティを入力します。それは完全なラウンドトリップを必要としないよう

ここで変更として個人的に取り付けが原因でロードするデータのビットクリーナーです

http://geekswithblogs.net/michelotti/archive/2009/11/27/attaching-modified-entities-in-ef-4.aspx

関連する問題