Julie Lerman による EF Code First チュートリアル ( http://msdn.microsoft.com/en-us/data/gg715119 ) に基づいて、次のコード スニペットのようなものを使用して、MVC 4 アプリケーションでモデルを更新しています。
public ActionResult Edit(int id, Person person)
{
using (var db = new MyDbContext())
{
person.Address = db.Addresses.Find(312);
db.Entry(person).State = EntityState.Modified;
db.SaveChanges();
}
}
これにより、Person オブジェクトのすべてのスカラー プロパティが保存されますが、新しい Address への参照は保存されません。デバッグ中に、私の DbContext が更新された人を認識していることがわかります。SaveChanges() を呼び出した後、ChangeTracker は正しい Address と State == Unchanged を持つ新しい人物を取得します。しかし、次にデータベースを見ると、新しいアドレスではなく古いアドレスが表示されます...
私は何か間違ったことをしていますか?この動作は設計によるものですか?
前もって感謝します!
説明:
この質問は、一部の純粋なオブジェクト データベース (db4o など) の動作に触発されており、DbContext API (または EF 一般) の内部動作に関するものです。
ステートメントを次のようにわずかに変更すると、次のようになります。
using (var db = new MyDbContext())
{
var p = db.Person.Find(person.Id);
// Variable p is now a person's proxy...
db.Entry(p).CurrentValues.SetValues(person);
// The above statement seems unnecessary, but it is actually required...
p.Address = db.Addresses.Find(312);
db.SaveChanges();
}
期待どおり、すべてが保存されます。
アーノルド氏が示唆したように、以前の (単純な) 構文を使用してオブジェクトの参照とそのスカラー プロパティの両方を更新できるようにするためだけに、モデルで外部キーの関連付けを使用する必要があるのはなぜですか? 人が他のオブジェクトへのすべての正しい参照を持っている db.Entry(person) を呼び出した後、なぜ EF はそれらを完全に無視し (多くのオブジェクト データベースとは対照的に)、SaveChanges() の呼び出しでスカラーを更新するだけなのですか?