我有两个一对一关系的模型类:
class Person
{
public int PersonID { get; set; }
public int DetailPersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DetailPerson DetailPerson { get; set; }
}
class DetailPerson
{
public int DetailPersonID { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
以及编辑页面视图的代码:
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.PersonID)
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)
@Html.LabelFor(m => m.DetailPerson.Address)
@Html.TextBoxFor(m => m.DetailPerson.Address)
@Html.LabelFor(m => m.DetailPerson.PhoneNumber)
@Html.TextBoxFor(m => m.DetailPerson.PhoneNumber)
<input type="submit" value="Edit">
}
EF脚手架使用此代码更新数据:
db.Entry(person).State = System.Data.EntityState.Modified;
db.saveChanges();
当我提交编辑表单时,我收到如下错误:
无法插入外键值,因为不存在相应的主键值。 [外键约束名称= FK_dbo.People_dbo.DetailPersons_DetailPersonID]
但如果我这样做:
Person p = db.Persons.Find(person.PersonID);
p.DetailPerson = person.DetailPerson;
p.FirstName = person.FirstName;
p.LastName = person.LastName;
db.saveChanges();
无错误地更新数据成功
我想知道为什么第一种方式会导致错误, 当我在包含 EntityState.Modified 的行设置断点时, 但外键值(DetailPersonID)为0。 然后,我在编辑表单上添加了@ Html.HiddenFor(m =&gt; m.DetailPersonID)。
我收到了另一个错误:
发生了引用完整性约束违规:定义引用约束的属性值在关系中的主体和从属对象之间不一致。
我仍然在另一方面更新数据库, 我只是好奇为什么EF标准更新数据的第一种方法出错了。
答案 0 :(得分:0)
如果存在一对一关系,则不应使用两个类,因为EF无论如何都会将db规范化为相应的表单。像这样结合你的课程。
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
如果你必须有单独的课程(不推荐),请这样做:
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DetailPersonID { get; set; }
public virtual DetailPerson DetailPerson { get; set; }
}
public class DetailPerson
{
public int PersonID { get; set; }
public virtual Person Person { get; set; }
public int DetailPersonID { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
然后当您检索对象时,请执行以下操作:
// include the detail when retrieving the parent
Person person = db.People.Include(p=>p.DetailPerson).Single(p=>p.PersonId == whateverIdYou Need);
// modify whatever you like
person.DetailPerson.Address = "my new address";
// then your previous statement will work
db.Entry(person).State = System.Data.EntityState.Modified;
db.saveChanges();