14

My update method is not working in an ASP.NET MVC 3 application. I have used the following EF 4.1 code:

[HttpPost]
public ActionResult UpdateAccountDetails(Account account)
{
    if (ModelState.IsValid)
    {
        service.SaveAccount(account);
    }
}

and SaveAccount looks like this:

internal void SaveAccount(Account account) {         
    context.SaveChanges();
}
Yakimych
  • 17,612
  • 7
  • 52
  • 69
DotnetSparrow
  • 27,428
  • 62
  • 183
  • 316

5 Answers5

21
internal void SaveAccount(Account account) {

    // Load current account from DB
    var accountInDb = context.Accounts.Single(a => a.Id == account.Id);

    // Update the properties
    context.Entry(accountInDb).CurrentValues.SetValues(account);

    // Save the changes
    context.SaveChanges();
}

Alternative:

internal void SaveAccount(Account account) {

    context.Entry(account).State = EntityState.Modified;
    context.SaveChanges();
}
Slauma
  • 175,098
  • 59
  • 401
  • 420
6

The problem here is that you're not accounting for the fact that Web pages are stateless. You probably pupulate your page with the account data returned from the database, but then the object is destroyed at the end of the request.

On postback, a new Acccount object is created by the model binder, but this one is not hooked up to the database, so your database context has no idea that it even exists. So when you call SaveChanges, nothing has changed as far as it is concerned.

You have to either get a new Account object from the database and update it's fields with the data from the model binder created Account, or attach the new account object to the database.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
2

This article should help

http://msdn.microsoft.com/en-us/library/bb896271.aspx

You may need to add context.Accounts.Attach(account); to reattach your entity to the context

msmucker0527
  • 5,164
  • 2
  • 22
  • 36
2

You aren't making any changes, so there is really nothing to be saved. The simplest way may be doing the following:

internal void SaveAccount(Account account)
{
    context.Attach(account);
    ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(account);
    entry.SetModified();

    context.SaveChanges();
}
Yakimych
  • 17,612
  • 7
  • 52
  • 69
1

If you're using an .edmx model in your application, make sure the property StoreGeneratedPattern is set to none for all the fields that have to be updated.

EF doesn't tell you, and acts like it is storing the changes to the database, when in fact it's not.

Kai Hartmann
  • 3,106
  • 1
  • 31
  • 45