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

时间:2015-07-23 14:04:30

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

使用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 official似乎过于复杂(请参阅添加部分 教师编辑页面的课程分配)加上需要 我要明确写出Customer的所有参数)
  2. this popular thread关于SO。方法3看起来像我需要但我无法更新导航属性。

1 个答案:

答案 0 :(得分:0)

我认为没必要两次调用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();