Updating related data with Entity Framework 6 in MVC 5

Using EntityFramework 6, I would like to update the Customer in the following scenario:

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;}
}

      

This is my ViewModel for the edit view:

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

      

This is my 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);
    }

      

This works and both scalar properties and consultants are updated from the edit view. However, I am doing two _db.SaveChanges();

in my controller. Is there a less complicated way to update Customer

? Since it Customer

has many properties, I would rather not do manual mapping of all parameters on Customer

and vm.Customer

.

I found the following resources:

  • the official asp.net seems too complicated (see the section Adding a Course Assignment on the instructor edit page) plus would have required me to explicitly write all the Client parameters)
  • this popular thread on SO. Method 3 looks like what I need, but I was unable to update the navigation property.
+3


source to share


1 answer


I don't think there is a need to call SaveChanges twice.

Have you tried something like this:

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

      



Edit:

Ok, not sure if this will work, but you can try using 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();

      

0


source







All Articles