在MVC 5中使用实体框架6更新相关数据

本文关键字:更新 数据 框架 实体 MVC | 更新日期: 2023-09-27 18:04:11

使用EntityFramework 6,我想在以下场景中更新Customer:

public class Customer
{
    public int Id {get; set;}
    // 100 more scalar properties
    public virtual IList<Consultant> Consultants {get;set;}
}
public class Consultant
{
    public int Id {get; set;}
    public virtual IList<Customer> Customers{get;set;}
}

这是我编辑视图的ViewModel:

public class CustomerViewModel
{
    public string[] SelectedConsultants { get; set; }
    public IEnumerable<Consultants> AllConsultants{ get; set; }
    public Customer Customer{ get; set; }
}

这是我的Edit-ActionMethod:

    [HttpPost]
    public ActionResult Edit(CustomerViewModel vm)
    {
        if (ModelState.IsValid)
        {
            // update the scalar properties on the customer
            var updatedCustomer = vm.Customer;
            _db.Customers.Attach(updatedCustomer );
            _db.Entry(updatedCustomer ).State = EntityState.Modified;
            _db.SaveChanges();
            // update the navigational property [Consultants] on the customer
            var customer = _db.Customers
                        .Include(i => i.Customers)
                        .Single(i => i.Id == vm.Customer.Id);
            Customer.Consultants.Clear();
            _db.Consultants.Where(x => vm.SelectedConsultants
                       .Contains(x.Id)).ToList()
                       .ForEach(x => customer.Consultants.Add(x));
            _db.Entry(customer).State = EntityState.Modified;
            _db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(vm);
    }

这可以工作,并且标量属性和顾问都可以从编辑视图中更新。然而,我在控制器中做了两个_db.SaveChanges();。是否有更简单的方法来更新Customer ?因为Customer有许多属性,我最好不要在Customervm.Customer上手动匹配所有参数。

我找到了以下资源:

  1. asp.net官方似乎过于复杂(参见添加一节)课程作业的讲师编辑页)加上要求我明确地写所有参数的客户)
  2. 这个流行的线程在SO。方法3看起来像我需要的,但我无法获得导航属性更新。

在MVC 5中使用实体框架6更新相关数据

我认为没有必要两次调用SaveChanges。

你试过这样做吗?

      var customer = _db.Customers
                        .Where(c => c.Id== vm.Customer.Id)
                        .Include(c => c.Consultants)
                        .SingleOrDefault();
      customer.Consultants = _db.Consultants
                                .Where(x => vm.SelectedConsultants.Contains(x.Id)).ToList();
      _db.SaveChanges();
编辑:

好吧,不确定这是否会工作,但你可以尝试使用Automapper:

            var customer = Mapper.Map<Customer>(vm.Customer);
            _db.Entry(customer).State = EntityState.Modified;
            customer.Consultants = _db.Consultants.Where(x => vm.SelectedConsultants.Contains(x.Id)).ToList();
            _db.SaveChanges();