3

我有两个一对一关系的模型类:

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 => m. DetailPersonID)在编辑表单上。

我得到另一个错误:

发生参照完整性约束冲突:定义参照约束的属性值在关系中的主体对象和从属对象之间不一致。

我仍然以另一种方式更新数据库,我只是好奇为什么第一种方式是 EF 标准来更新数据会出错。

4

1 回答 1

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();
于 2013-03-26T19:16:29.313 回答