我对3个表之间的关系有一些问题。所有这些之间存在多对多的关系 - 我的模型类如下所示:
public partial class Bus
{
public Bus()
{
this.Lines = new HashSet<Line>();
this.Drivers = new HashSet<Driver>();
}
public int BusID { get; set; }
public string RegNum { get; set; }
[StringLength(3)]
public string Status { get; set; }
public virtual ICollection<Line> Lines { get; set; }
public virtual ICollection<Driver> Drivers { get; set; }
}
public partial class Driver
{
public Driver()
{
this.Buses = new HashSet<Bus>();
}
public int DriverID { get; set; }
public string DriverName { get; set; }
public string DriverSurname { get; set; }
[StringLength(3)]
public string Status { get; set; }
[Display(Name = "Driver")]
public string DriverInfo
{
get
{
return DriverName + " " + DriverSurname;
}
}
public virtual ICollection<Bus> Buses { get; set; }
}
public partial class Line
{
public Line()
{
this.Schedules = new HashSet<Schedule>();
this.Buses = new HashSet<Bus>();
}
public int LineID { get; set; }
public int LineNumber { get; set; }
public string Direction { get; set; }
[Display(Name = "Line: Direction")]
public string LineInfo
{
get
{
return LineNumber + ": " + Direction;
}
}
public virtual ICollection<Bus> Buses { get; set; }
}
的DbContext:
public partial class ModelEntities : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Bus> Buses { get; set; }
public virtual DbSet<Driver> Drivers { get; set; }
public virtual DbSet<Line> Lines { get; set; }
}
根据:https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application。 我通过创建ViewModel并更新BusController来处理Bus&lt; - &gt; Driver连接。我可以使用复选框(驱动程序列表)正确创建和编辑总线。 但是,我有一个问题是使用Bus&lt; - &gt; Lines。
ViewModel文件夹由3个类组成(AssignedDriverData,BusIndexData,AssignedLineData):
public class AssignedDriverData
{
public int DriverID { get; set; }
public string DriverName { get; set; }
public string DriverSurname { get; set; }
public string DriverInfo
{
get
{
return DriverName + " " + DriverSurname;
}
}
public bool Assigned { get; set; }
}
public class BusIndexData
{
public IEnumerable<Bus> Buses { get; set; }
public IEnumerable<Driver> Drivers { get; set; }
public IEnumerable<Line> Lines { get; set; }
}
public class AssignedLineData
{
public int LineID { get; set; }
public int LineNumber { get; set; }
public string Direction { get; set; }
public string LineInfo
{
get
{
return LineNumber + ": " + Direction;
}
}
public bool Assigned { get; set; }
}
BusController(包括更改行创建和编辑):
public class BusesController : Controller
{
private ModelEntities db = new ModelEntities();
// GET: Buses
public ActionResult Index()
{
return View(db.Buses.ToList());
}
// GET: Buses/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Bus bus = db.Buses.Find(id);
if (bus == null)
{
return HttpNotFound();
}
return View(bus);
}
// GET: Buses/Create
public ActionResult Create()
{
//***************** adding drivers ******************//
var bus = new Bus();
bus.Drivers = new List<Driver>();
PopulateAssignedDriverData(bus);
bus.Lines = new List<Line>(); //********* adding lines*********************//
PopulateAssignedLineData(bus); //********* adding lines*********************//
//************************************************//
return View();
}
// POST: Buses/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "BusID,RegNum,Status")] Bus bus, string[] selectedDrivers, string[] selectedLines)
{
//******************* adding drivers **********************//
if (selectedDrivers != null)
{
bus.Drivers = new List<Driver>();
foreach (var course in selectedDrivers)
{
var driverToAdd = db.Drivers.Find(int.Parse(course));
bus.Drivers.Add(driverToAdd);
}
}
//************************************************//
//******************* adding lines **********************//
if (selectedLines != null)
{
bus.Lines = new List<Line>();
foreach (var line in selectedLines)
{
var lineToAdd = db.Lines.Find(int.Parse(line));
bus.Lines.Add(lineToAdd);
}
}
//************************************************//
if (ModelState.IsValid)
{
db.Buses.Add(bus);
db.SaveChanges();
return RedirectToAction("Index");
}
//************************************************//
PopulateAssignedDriverData(bus);
PopulateAssignedLineData(bus);
//************************************************//
return View(bus);
}
// GET: Buses/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//************** editing drivers ********************//
Bus bus = db.Buses
.Include(i => i.Drivers)
.Include(i => i.Lines) //****** for editing lines ******//
.Where(i => i.BusID == id)
.Single();
PopulateAssignedDriverData(bus);
//************************************************//
if (bus == null)
{
return HttpNotFound();
}
return View(bus);
}
// POST: Buses/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
//************** editing with drivers and lines ********************//
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int? id, string[] selectedDrivers, string[] selectedLines)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var busToUpdate = db.Buses
.Include(i => i.Drivers)
.Include(i => i.Lines) //****** added for lines *******//
.Where(i => i.BusID == id)
.Single();
if (TryUpdateModel(busToUpdate, "",
new string[] { "BusID,RegNum,Status" }))
{
try
{
UpdateBusDrivers(selectedDrivers, busToUpdate);
UpdateBusDrivers(selectedLines, busToUpdate); //****** added for lines *******//
db.SaveChanges();
return RedirectToAction("Index");
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
PopulateAssignedDriverData(busToUpdate);
PopulateAssignedLineData(busToUpdate); //****** added for lines *******//
return View(busToUpdate);
}
//************************************************//
// GET: Buses/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Bus bus = db.Buses.Find(id);
if (bus == null)
{
return HttpNotFound();
}
return View(bus);
}
// POST: Buses/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Bus bus = db.Buses.Find(id);
db.Buses.Remove(bus);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
//********************** adding drivers ******************//
private void PopulateAssignedDriverData(Bus bus)
{
var allDrivers = db.Drivers;
var busDrivers = new HashSet<int>(bus.Drivers.Select(c => c.DriverID));
var viewModel = new List<AssignedDriverData>();
foreach (var driver in allDrivers)
{
viewModel.Add(new AssignedDriverData
{
DriverID = driver.DriverID,
DriverName = driver.DriverName,
DriverSurname = driver.DriverSurname,
Assigned = busDrivers.Contains(driver.DriverID)
});
}
ViewBag.Drivers = viewModel;
}
//************************************************//
//**************** editing drivers ***********************//
private void UpdateBusDrivers(string[] selectedDrivers, Bus busToUpdate)
{
if (selectedDrivers == null)
{
busToUpdate.Drivers = new List<Driver>();
return;
}
var selectedDriversHS = new HashSet<string>(selectedDrivers);
var busDrivers = new HashSet<int>
(busToUpdate.Drivers.Select(c => c.DriverID));
foreach (var driver in db.Drivers)
{
if (selectedDriversHS.Contains(driver.DriverID.ToString()))
{
if (!busDrivers.Contains(driver.DriverID))
{
busToUpdate.Drivers.Add(driver);
}
}
else
{
if (busDrivers.Contains(driver.DriverID))
{
busToUpdate.Drivers.Remove(driver);
}
}
}
}
//************************************************//
//********************** adding lines ******************//
private void PopulateAssignedLineData(Bus bus)
{
var allLines = db.Lines;
var busLines = new HashSet<int>(bus.Lines.Select(c => c.LineID));
var viewModel = new List<AssignedLineData>();
foreach (var line in allLines)
{
viewModel.Add(new AssignedLineData
{
LineID = line.LineID,
Direction = line.Direction,
LineNumber = line.LineNumber,
Assigned = busLines.Contains(line.LineID)
});
}
ViewBag.Lines = viewModel;
}
//************************************************//
//**************** editing lines ***********************//
private void UpdateBusLines(string[] selectedLines, Bus busToUpdate)
{
if (selectedLines == null)
{
busToUpdate.Lines = new List<Line>();
return;
}
var selectedLinesHS = new HashSet<string>(selectedLines);
var busLines = new HashSet<int>
(busToUpdate.Lines.Select(c => c.LineID));
foreach (var line in db.Lines)
{
if (selectedLinesHS.Contains(line.LineID.ToString()))
{
if (!busLines.Contains(line.LineID))
{
busToUpdate.Lines.Add(line);
}
}
else
{
if (busLines.Contains(line.LineID))
{
busToUpdate.Lines.Remove(line);
}
}
}
}
//************************************************//
}
不幸的是,向总线添加任何行都失败了。 如何处理总线表的这2个多对多关系? 我很欣赏你的提示;) KB
答案 0 :(得分:1)
您是否阅读了Fluent API?
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Bus>().HasMany(b => b.Drivers).WithMany(d => d.Buses).Map(m =>
{
m.MapLeftKey("BusId");
m.MapRightKey("DriverID");
m.ToTable("BusDriverJoinTable");
});
modelBuilder.Entity<Bus>().HasMany(b => b.Lines).WithMany(l=>l.Buses).Map(m =>
{
m.MapLeftKey("BusId");
m.MapRightKey("LineID");
m.ToTable("BusLineJoinTable");
});
}