Reputation: 442
I have a many to many relationship b/w drivers and vehicle entity, at the time of driver creation, many vehicles can be assigned to a driver, it works fine, but when I want to edit and update records I am getting null collection of vehicles,
Here are my Models :
public class Driver {
public int driverId {get;set;}
public string Name {get;set;}
public virtual ICollection<Vehicle> Vehicles {get;set;}
}
public class Vehicle {
public int Vehicle_Id {get;set;}
public string Vehicle_Type_Name {get;set;}
public virtual ICollection<Driver> Drivers {get;set;}
}
Here I define the relationship:
modelBuilder
.Entity<Driver>()
.HasMany<Vehicle>(d => d.Vehicles)
.WithMany(d => d.Drivers).Map(
cs =>
{
cs.MapLeftKey("DriverId")
.MapRightKey("VehicleId")
.ToTable("DriversVehicles");
});
And my driver View Model
public class DriverViewModel
{
public DriverViewModel()
{
SelectedVehicles=new List<int>();
VehicleList = new List<Vehicle>();
}
public Driver driver { get; set; }
public List<int> SelectedVehicles { get; set; }
public List<Vehicle> VehicleList { get; set; }
}
And here is driver Edit() Controller Action :
public ActionResult Edit(int id = 0)
{
DriverViewModel DriverVm = new DriverViewModel();
var list = db.vehicles.Select(
v => new { v.Vehicle_Id,v.Vehicle_Type_Name }).ToList();
DriverVm.driver = db.drivers.Find(id);
foreach (var item in list)
{
DriverVm.VehicleList.Add(new Vehicle { Vehicle_Id = item.Vehicle_Id, Vehicle_Type_Name = item.Vehicle_Type_Name });
}
foreach (var item in DriverVm.driver.Vehicles)
{
DriverVm.SelectedVehicles.Add(item.Vehicle_Id);
}
return View(DriverVm);
}
And here is POST action for edit:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(DriverViewModel driverVm)
{
var list = db.vehicles.Select(v =>
new { v.Vehicle_Id, v.Vehicle_Type_Name }).ToList();
foreach (var item in list)
{
driverVm.VehicleList.Add(
new Vehicle {
Vehicle_Id = item.Vehicle_Id,
Vehicle_Type_Name = item.Vehicle_Type_Name
});
}
if (ModelState.IsValid)
{
db.Entry(driverVm.driver).State = EntityState.Modified;
db.SaveChanges();
List<Vehicle> vhcls = new List<Vehicle>();
Driver driver = db.drivers.Find(driverVm.driver.driverId);
vhcls = driver.Vehicles.ToList();
foreach (Vehicle veh in vhcls)
{
driver.Vehicles.Remove(veh);
}
db.SaveChanges();
foreach (var item in driverVm.SelectedVehicles)
{
Vehicle vehicle = db.vehicles.Find(item);
driverVm.driver.Vehicles.Add(vehicle);
}
db.SaveChanges();
TempData["DriverSuccess"] = "1";
return RedirectToAction("Edit");
}
else
{
ViewBag.DriverError = "1";
}
return View(driverVm);
}
The actual problem is here :
Driver driver = db.drivers.Find(driverVm.driver.driverId);
vhcls = driver.Vehicles.ToList();
foreach (Vehicle veh in vhcls)
{
driver.Vehicles.Remove(veh);
}
db.SaveChanges()
The list "vhcls" in the above code is empty, it should contain the vehicles associated with drivers, but "driver" object contains Null collection in "driverVm.driver.Vehicles" instead of having associated vehicles, I am wandering badly but can't find the solution..Please help......
Upvotes: 0
Views: 31
Reputation: 2857
Just using find
won't include related entities. It's very likely that driver contains the right entity, but that the Vehicles collection is empty.
Try using Include
to make sure that the related entities will be included, and FirstOrDefault
to emulate the result of Find
.
Driver driver = db.drivers
.Include(d => d.Vehicles)
.FirstOrDefault(d => d.Id == driverVm.driver.driverId);
vhcls = driver.Vehicles.ToList();
Edit: I initially missed that you were already using Lazy Loading, so I adjusted the answer a bit.
Upvotes: 1