Updating only part of a model

2020-03-30 16:15发布

问题:

I'm using ASP.NET MVC 3 and Entity Framework Code First. I have a page (using Razor View Engine) which allows a user to update parts of a model (Product):

@Html.LabelFor(model => model.Overview) @Html.TextAreaFor(model => model.Overview)

@Html.LabelFor(model => model.Description)
@Html.TextAreaFor(model => model.Description)

@Html.HiddenFor(model => model.ProductId)

My controller method looks like this:

[HttpPost]
public ActionResult Update(Product product)
{
  db.Products.Attach(product);
  db.SaveChanges();
}

All I want to do is to update the Overview and Description attributes of the Product model. However, when I run the code the model is not updated in the database, and I don't get any errors.

When I inspect the product object whilst debugging, I see that whilst the ProductId, Overview and Description fields are correct (as per the FORM POST), the other fields are NULLs (which I would expect).

I'm wondering if the incomplete state of the product object is causing it not to save to the database?

Here is the model:

public class Product { public int ProductId { get; set; }

    [Required(ErrorMessage = "Please enter a description")]
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }

    [DataType(DataType.MultilineText)]
    public string Overview { get; set; }

    public int SupplierId { get; set; }
    public virtual Supplier Supplier { get; set; }
}

回答1:

When it comes to editing, try selecting an existing record from the database first (the one you want to edit), then update it with the values collected from your form (i.e. the model passed into your controller action), then save it.

E.g.

[HttpPost]
public ActionResult Update(Product productPassedInFromView)
{ 
    Product productToEdit = db.Products.Find(productPassedInFromView.ID);

    productToEdit.Property1 = productPassedInFromView.Property1;
    productToEdit.Property2 = productPassedInFromView.Property2;
    //Continue for all the fields you want to edit.

    db.SaveChanges();
}


回答2:

If you know which properties of entity you will update, you can use ChangeTracker in EF to mark only those properties as changed. Below is a modified example from excellent book [Programming Entity Framework: DbContext] (http://shop.oreilly.com/product/0636920022237.do):

db.Products.Attach(product);
var entry = db.Entry(product);
entry.State = EntityState.Unchanged;
entity.Property(p => p.Overview).IsModified = true;
entity.Property(p => p.Description).IsModified = true;
db.SaveChanges();

This will save you a roundtrip to database. But of course it works only when you know which properties are changing. There are some other ways to achieve this, but this one is most straightforward.