【问题标题】:Many to many MVC 5 Model first write to join table多对多 MVC 5 模型首先写入连接表
【发布时间】:2015-01-14 12:57:54
【问题描述】:

我有一个“部分”工作代码,其中包含团队和玩家(以及连接表 TeamPlayers)之间的多对多关系。 Team 和 Player 端的下拉菜单不起作用。虽然数据存储在 db(Player 和 Team 表)中,但不存储在连接表 TeamPlayers 中。

我希望在我的视图中能够连接当前玩家和当前团队,也就是在我的联结表中将当前 TeamId 保存到 TeamId(并将 PlayerId 保存到 PlayerId)。最后插入步骤是....我完全卡住了.... 感谢各种帮助。请参阅下面的我的代码,并在必要时询问更多信息。提前致谢! /那只猪

模型 m2mContext.cs

public class m2mContext : DbContext
    {
        // You can add custom code to this file. Changes will not be overwritten.
        // 
        // If you want Entity Framework to drop and regenerate your database
        // automatically whenever you change your model schema, please use data migrations.
        // For more information refer to the documentation:
        // http://msdn.microsoft.com/en-us/data/jj591621.aspx

        public m2mContext() : base("name=m2mContext")
        {
        }

        public System.Data.Entity.DbSet<m2m.Models.Team> Teams { get; set; }

        public System.Data.Entity.DbSet<m2m.Models.Player> Players { get; set; }

    }

Model Team.cs

namespace m2m.Models
{
    public class Team
    {
        public int TeamId { get; set; }
        [Required]
        public string TeamName { get; set; }

        public int PlayerId { get; set; }
        public virtual ICollection<Player> Players { get; set; } // This is new

    }
}

模型播放器.cs

namespace m2m.Models
{
    public class Player
    {
        public int PlayerId { get; set; }
        public string PlayerName { get; set; }
        public int TeamId { get; set; }

        // public virtual Team Team { get; set; } // This is new

        public virtual ICollection<Team> Teams { get; set; }
    }
}

控制器 TeamController.cs

namespace m2m.Controllers
{
    public class TeamController : Controller
    {
        private m2mContext db = new m2mContext();

        // GET: Team
        public ActionResult Index()
        {
            return View(db.Teams.ToList());
        }

        // GET: Team/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Team team = db.Teams.Find(id);
            if (team == null)
            {
                return HttpNotFound();
            }
            return View(team);
        }

        // GET: Team/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Team/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 = "TeamId,TeamName,PlayerId")] Team team)
        {
            if (ModelState.IsValid)
            {
                db.Teams.Add(team);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(team);
        }

控制器 PlayerController.cs

namespace m2m.Controllers
{
    public class PlayerController : Controller
    {
        private m2mContext db = new m2mContext();

        // GET: Player
        public ActionResult Index()
        {
            return View(db.Players.ToList());
        }

        // GET: Player/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Player player = db.Players.Find(id);
            if (player == null)
            {
                return HttpNotFound();
            }
            return View(player);
        }

        // GET: Player/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Player/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 = "PlayerId,PlayerName,TeamId")] Player player)
        {
            if (ModelState.IsValid)
            {
                db.Players.Add(player);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(player);
        }

查看团队

创建

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Team</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.TeamName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.TeamName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.TeamName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PlayerId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.PlayerId, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.PlayerId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

查看播放器

创建

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Player</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.PlayerName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.PlayerName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.PlayerName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.TeamId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.TeamId, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.TeamId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

【问题讨论】:

    标签: c# entity-framework asp.net-mvc-5 many-to-many


    【解决方案1】:

    由于我的代表,我无法发表评论,所以我会发布一个可能的答案。

    我会将 TeamPlayers 添加到模型中,将方法添加到玩家和/或团队控制器以将它们添加到 TeamPlayer。

    public System.Data.Entity.DbSet<m2m.Models.TeamPlayer> TeamPlayer{ get; set; }
    

    在控制器中

    public ActionResult AddtoTeam(int? Teamid)
    public ActionResult AddPlayer(int? Playerid)
    

    不完全确定这是你想要的。

    【讨论】:

    • 创建一个显式模型来保存多对多关系是不必要的,除非您需要存储有关该关系的其他信息,例如团队中的某个角色。否则,您最好坚持使用 EF 创建的隐式连接表,因为 API 更易于使用。
    【解决方案2】:

    问题是您发布到属性PlayerId/TeamId。这是一个 M2M,所以这些字段不做任何事情。您必须提供一个多选,最终会发布一个 ID 列表。然后,您可以使用此发布的 id 列表从数据库中查找球员/球队并将其添加到各自的收藏中。

    【讨论】:

    • 这方面的代码很多,如果您需要进一步的指导,请参阅我写的关于这个主题的帖子:cpratt.co/…
    • 谢谢!我一遍又一遍地查看您的代码,但它对我不起作用...但我想我必须再次阅读您的代码..我还查看了来自 asp.net 的这篇文章 [link]asp.net/mvc/overview/getting-started/… 似乎涵盖我的问题
    • asp.net 文章从未真正涉及通过表单帖子保存 M2M 关系。是的,请再看看我写的内容,如果您有具体问题,请随时提问。
    猜你喜欢
    • 1970-01-01
    • 2015-02-25
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    相关资源
    最近更新 更多