geralvin
geralvin

Reputation: 73

[ask]asp.net mvc update database error

I have two model classes in one-to-one relationship:

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; }
}

and the code for the edit page view:

@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">

}

The EF scaffold uses this code to update data:

db.Entry(person).State = System.Data.EntityState.Modified;
db.saveChanges();

When I submit the edit form, I got an error like this:

A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = FK_dbo.People_dbo.DetailPersons_DetailPersonID ]

But if I do this:

Person p = db.Persons.Find(person.PersonID);
p.DetailPerson = person.DetailPerson;
p.FirstName = person.FirstName;
p.LastName = person.LastName;
db.saveChanges();

update data success without error

I want to know why the first way causse an error, when I set the breakpoint at the line containing EntityState.Modified, but the foreign key value ( DetailPersonID ) is 0. Then, I added @Html.HiddenFor(m => m.DetailPersonID) on the edit form.

I got another error:

A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

I still update database on the other way, I am just curious why the first way which is EF standart to update data got an error.

Upvotes: 3

Views: 744

Answers (1)

spadelives
spadelives

Reputation: 1628

You shouldn't use two classes if there is a one-to-one relationship since EF will normalize the db into the corresponding form anyway. Combine your classes like this.

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; }
}

if you must have separate classes (not recommended), do it like this:

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; }
}

Then when you retrieve your object, do it like this:

// 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();

Upvotes: 0

Related Questions