更新具有另一个类的类

时间:2012-04-10 16:56:16

标签: asp.net-mvc entity-framework-4

我有一个产品类:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Amount { get; set; }

    public virtual Brand Brand { get; set; }
}

我正在尝试更新模型:

[HttpPost]
public ActionResult Edit(Product product) 
{
    if (ModelState.IsValid) 
    {
        product.Brand = db.Brands.Find(product.Brand.Id);

        db.Entry(product).State = EntityState.Modified;
        db.SaveChanges();

        return RedirectToAction("Index");
    }
    return View(product);
}

问题在于我的所有属性都已更新但Brand! 我该怎么做才能更新它?


如果我这样做:

[HttpPost]
public ActionResult Edit(Product product) 
{
     if (ModelState.IsValid)  
     {
          db.Products.Attach(product);

          product.Brand = db
              .Brands
              .Find(2); // << with a static value

          db.Entry(product).State = EntityState.Modified;

          db.SaveChanges();

          return RedirectToAction("Index");
      }
      return View(product);
 }

它有效...但如果我在下面尝试这个,即使BrandId是2,它也不起作用:

    [HttpPost]
    public ActionResult Edit(Product product) 
    {
        if (ModelState.IsValid)  
        {
            db.Products.Attach(product);

            int BrandId = product.Brand.Id;

            product.Brand = db
                .Brands
                .Find(BrandId);

            db.Entry(product).State = EntityState.Modified;

            db.SaveChanges();

            return RedirectToAction("Index");
        }
        return View(product);
    }

1 个答案:

答案 0 :(得分:1)

您必须分别处理ProductBrand之间的关系。手动将状态设置为Modified不会影响关系。首先从数据库加载Brand(与产品一起)尤为重要,否则EF无法检测关系是否发生变化:

[HttpPost]
public ActionResult Edit(Product product) 
{
    if (ModelState.IsValid) 
    {
        var productInDB = db.Products.Include(p => p.Brand)
            .Single(p => p.Id == product.Id);

        // Update scalar properties
        db.Entry(productInDB).CurrentValues.SetValues(product);

        // Update relationship between product and brand
        if (product.Brand == null && productInDB.Brand != null)
            productInDB.Brand = null;
        else if (product.Brand != null && (productInDB.Brand == null
            || product.Brand.Id != productInDB.Brand.Id))
        {
            db.Brands.Attach(product.Brand);
            productInDB.Brand = product.Brand;
        }

        db.SaveChanges();

        return RedirectToAction("Index");
    }
    return View(product);
}

如果您在BrandId实体中引入外键属性Product并在视图中设置此product.BrandId而不是product.Brand.Id,则此过程会变得更加容易。在这种情况下,将状态设置为Modified将起作用,因为BrandId是标量属性。