user2062383
user2062383

Reputation: 959

Weird behavior from Create() method in MVC4 - new object getting set with ID = 0, saved as something else

I'm debugging this method for two cases: one where there is a parent, the other where there is no parent.

If there is no parent, the new Person has an id of 0 but never actually gets saved to the db.

If there is a parent, the new Person has an id of 0 in this method, but a new record is inserted into the db with the correct value (one more than the highest in the table).

What is going on here? I know I'm doing something wrong, I'm just not sure what.

I'm using EF Codefirst.

The code for the controller method:

[HttpPost]
public ActionResult Create(CreatePersonViewModel viewModel)
{
    if (ModelState.IsValid)
    {

        var parent = _db.Persons.FirstOrDefault(s => s.PersonId == viewModel.ParentId);

        var person = new Person() { Name = viewModel.Name };

        // if it has a parent, build new relationship
        if (parent != null)
        {
            person.Parent = parent;
            parent.Children.Add(person);
        };

        _db.Save();

        return RedirectToAction("detail", "person", new { personId = person.PersonId });
    }
    return View(viewModel);
}

Upvotes: 2

Views: 595

Answers (2)

Cristian Lupascu
Cristian Lupascu

Reputation: 40546

If there is no parent, the new Person has an id of 0 but never actually gets saved to the db.

That's because you never tell EF that it should persist the entity. You only create a new Person() and that's it.

You should do:

dbContext.AddToPersons(person);

before calling dbContext.SaveChanges().

In the case when there is a parent, person is saved because of its relationship with parent.

Update

Just occurred to me: If you're doing code first you might not have the AddToPersons(...) method available on the data context. If this is so, you can use dbContext.Persons.AddObject(person) instead.

Upvotes: 1

radu florescu
radu florescu

Reputation: 4363

The fact with you are referring to is auto increment ID for you object. It is controlled by your ORM. You may want to check this question

You may want to check this link from msdn

Remarks Refresh has the dual purpose of allowing an object to be refreshed with data from the data source and being the mechanism by which conflicts can be resolved. For more information, see Saving Changes and Managing Concurrency (Entity Framework). The order in which objects are refreshed is nondeterministic. After the Refresh method is called, the object’s original values will always be updated with the data source value, but the current values might or might not be updated with the data source value. This depends on the RefreshMode. The StoreWins mode means that the object should be updated to match the data source values. The ClientWins value means that only the changes in the object context will be persisted, even if there have been other changes in the data source. To ensure that an object has been updated by data source-side logic, you can call the Refresh method with the StoreWins value after you call the SaveChanges method.

Upvotes: 1

Related Questions