Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 with EF 4.1 and EntityState.Modified

Updating an object with MVC3

I have a model that I can modify, please see the sample below:

[HttpPost]
public ActionResult Edit(Company c)
{
       if (ModelState.IsValid)
       {
           db.Entry(c).State = EntityState.Modified;
           db.SaveChanges();
           return RedirectToAction("Index");
       }
       return View(c);
}

The model has other fields that are not showing in the view and cannot be modified by the user, but when I click the submit button the fields that were not showing in the view got set to null.

Can I somehow let EF know not to modify certain fields? Thanks.

like image 927
Benk Avatar asked Dec 05 '11 23:12

Benk


2 Answers

Generally it is better not to bind to the entity object directly, rather create an edit model and bind to that.

After all.. whats to stop someone posting back values you don't want changed with this approach?

The main problem here is the fact that mvc model binding changes the properties in the model before its in a context therefore the entity framework doesn't know which values have changed (and hence which should be updated)

You've mitigated that slightly with db.Entry(c).State = EntityState.Modified; but that tells the entity framework that the whole record has been updated.

I would normally do the following:

  1. Bind to a model specifically for this controller first
  2. Create an instance of the entity class you want to update, set the Id accordingly and attach it to the context
  3. Update the properties on the entity to be the same as the model you binded to (object is attached and therefore entity framework is tracking which columns are being changed now)
  4. SaveChanges

Step 3 is a bit tedious therefore consider using a tool like automapper to make things easier

Edit:

    [HttpPost]
    public ActionResult Edit(Company c)
    {
        if (ModelState.IsValid)
        {
            Company dbCompayObjct = new Company { companyId = c.companyId };
            db.Company.Attach(dbCompayObjct);

            dbCompanyObjct.CompanyName = c.CompanyName;
            dbCompanyObjct.City = c.City;

            db.SaveChanges();

            return RedirectToAction("Index");
        } 
        return View(c);
    }
like image 110
Martin Booth Avatar answered Nov 19 '22 04:11

Martin Booth


You are apparently overwriting your existing record with an incomplete record. When you use the method above, it will completely replace the existing one.

You either need to fill in all the fields you don't want to replace with the existing values, or you need to get the existing record and modify the fields you want to modify, then save it.

like image 25
Erik Funkenbusch Avatar answered Nov 19 '22 04:11

Erik Funkenbusch