[问] asp.net mvc更新数据库错误

时间:2013-03-12 04:50:31

标签: asp.net-mvc asp.net-mvc-3 entity-framework asp.net-mvc-4

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

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标准更新数据的第一种方法出错了。

1 个答案:

答案 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();