C# 一个表的两个多对多关系

C# 一个表的两个多对多关系,c#,asp.net-mvc,entity-framework,many-to-many,C#,Asp.net Mvc,Entity Framework,Many To Many,我对3个表之间的关系有一些问题。它们之间存在多对多关系-我的模型类如下所示: public partial class Bus { public Bus() { this.Lines = new HashSet<Line>(); this.Drivers = new HashSet<Driver>(); } public int BusID { get; set; } public string R

我对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; }
}
公共部分类总线
{
公共巴士()
{
this.Lines=newhashset();
this.Drivers=newhashset();
}
公共int BusID{get;set;}
公共字符串RegNum{get;set;}
[第(3)款]
公共字符串状态{get;set;}
公共虚拟ICollection行{get;set;}
公共虚拟ICollection驱动程序{get;set;}
}
公共部分类驱动程序
{
公共司机()
{
this.bus=new HashSet();
}
public int DriverID{get;set;}
公共字符串驱动器名{get;set;}
公共字符串驱动器urname{get;set;}
[第(3)款]
公共字符串状态{get;set;}
[显示(Name=“Driver”)]
公共字符串驱动程序信息
{
得到
{
返回DriverName+“”+DriverSurname;
}
}
公共虚拟ICollection总线{get;set;}
}
公共部分类线
{
公共电话线()
{
this.Schedules=newhashset();
this.bus=new HashSet();
}
public int LineID{get;set;}
公共整数行号{get;set;}
公共字符串方向{get;set;}
[显示(名称=“行:方向”)]
公共字符串LineInfo
{
得到
{
返回行号+“:”+方向;
}
}
公共虚拟ICollection总线{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; }
}
公共部分类ModelEntities:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
抛出新代码FirstException();
}
公共虚拟数据库集总线{get;set;}
公共虚拟数据库集驱动程序{get;set;}
公共虚拟数据库集行{get;set;}
}
根据:。 我通过创建视图模型和更新总线控制器来处理总线驱动程序连接。我能够使用复选框(驱动程序列表)正确地创建和编辑总线。 然而,我有一个问题,做同样的总线

ViewModel文件夹由3个类组成(AssignedDriverData、BusIndexData、AssignedLineData):

公共类分配的数据
{
public int DriverID{get;set;}
公共字符串驱动器名{get;set;}
公共字符串驱动器urname{get;set;}
公共字符串驱动程序信息
{
得到
{
返回DriverName+“”+DriverSurname;
}
}
公共布尔赋值{get;set;}
}
公共类业务扩展数据
{
公共IEnumerable总线{get;set;}
公共IEnumerable驱动程序{get;set;}
公共IEnumerable行{get;set;}
}
公共类AssignedLineData
{
public int LineID{get;set;}
公共整数行号{get;set;}
公共字符串方向{get;set;}
公共字符串LineInfo
{
得到
{
返回行号+“:”+方向;
}
}
公共布尔赋值{get;set;}
}
总线控制器(包括线路创建和编辑的更改):

公共类总线控制器:控制器
{
私有模型实体db=新模型实体();
//获取:公交车
公共行动结果索引()
{
返回视图(db.bus.ToList());
}
//获取:公交车/详细信息/5
公共行动结果详细信息(int?id)
{
if(id==null)
{
返回新的HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
总线=db.Bus.Find(id);
如果(总线==null)
{
返回HttpNotFound();
}
返回视图(总线);
}
//获取:总线/创建
公共操作结果创建()
{
//*****************添加驱动程序******************//
var总线=新总线();
bus.Drivers=新列表();
PopulatesSignedDriverData(总线);
bus.Lines=new List();//**********添加行*********************//
PopulatesSignedLineData(总线);//**********添加行*********************//
//************************************************//
返回视图();
}
//邮政:公交车/创建
//若要防止套印攻击,请启用要绑定到的特定属性,例如
//更多详细信息请参见http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
公共操作结果创建([Bind(Include=“BusID,RegNum,Status”)]总线,字符串[]selectedDrivers,字符串[]selectedLines)
{
//*******************添加驱动程序**********************//
if(selectedDrivers!=null)
{
bus.Drivers=新列表();
foreach(选定河流中的var课程)
{
var driverToAdd=db.Drivers.Find(int.Parse(course));
bus.Drivers.Add(driverToAdd);
}
}
//************************************************//
//*******************添加行**********************//
如果(selectedLines!=null)
{
bus.Lines=新列表();
foreach(选定行中的var行)
{
var lineToAdd=db.Lines.Find(int.Parse(line));
bus.Lines.Add(lineToAdd);
}
}
//************************************************//
if(ModelState.IsValid)
{
db.bus.Add(总线);
db.SaveChanges();
返回操作(“索引”);
}
//************************************************//
PopulatesSignedDriverData(总线);
PopulatesSignedLineData(总线);
//************************************************//
返回视图(总线);
}
//获取:总线/编辑/5
公共行动结果编辑(int?id)
{
if(id==null)
{
返回新的HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//**************编辑驱动程序
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; }
}
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);
                }
            }
        }
    }
    //************************************************//
 }
    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");
        });
    }