基于 Julie Lerman ( http://msdn.microsoft.com/en-us/data/gg715119 ) 的 EF Code First 教程,我正在使用类似于以下代码片段的内容在 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 对象的所有标量属性,但不会保存对新地址的引用。在调试时,我可以看到我的 DbContext 知道更新的人。调用 SaveChanges() 后,ChangeTracker 拥有具有正确地址和状态 == 未更改的新人员。但是,下次我查看数据库时,我看到的是旧地址而不是新地址...
难道我做错了什么?这种行为是设计使然吗?
提前致谢!
澄清:
这个问题的灵感来自一些纯对象数据库(如 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();
}
正如预期的那样,一切都被保存了。
令我困惑的是,为什么我们必须在我们的模型中使用外键关联,正如 Arnold 先生所建议的那样,只是为了能够使用以前的(简单)语法来更新对象的引用及其标量属性?在调用 db.Entry(person) 之后,该人拥有对其他对象的所有正确引用,为什么 EF 完全忽略它们(与许多对象数据库相比)并且只是在调用 SaveChanges() 时更新其标量?