使用Entity Framework 6在MVC 5中更新相关数据

3
使用EntityFramework 6,我想在以下场景中更新客户信息:
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; }
}

这是我的编辑-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官方文档似乎过于复杂(请参见将课程分配添加到讲师编辑页面部分),并且需要显式编写所有Customer的参数。
  2. 这个流行的线程在SO上。第3种方法看起来就是我需要的,但我无法更新导航属性。
1个回答

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();

嗨,艾伦,你的建议没有考虑到客户的标量属性可能也已经更改了(客户名称等)。此外,我认为Entity Framework希望使用.Add或.Remove来添加和删除ICollection中的内容。编辑:好的,我刚刚检查过了,它确实保存了顾问们 ;o) - peter
你可以尝试使用Automapper将vm中的属性映射到模型中。 - Alan Macgowan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接