【问题标题】:Saving Many to Many in MVC asp.net在 MVC asp.net 中保存多对多
【发布时间】:2016-08-22 09:20:07
【问题描述】:

我阅读了很多关于 MVC 的内容。但是直到现在还没有明确的答案如何处理多对多关系,因为这些教程结果中的许多都有相同的错误。
我正在使用数据库优先方法,我的应用程序应该添加用户,在添加用户时我应该有一个角色列表,我可以将这些角色添加到这个用户,或者相反我可以有用户列表和编辑的角色,正如我们所知当我将带有中断表的数据库添加到 ado.net 时,关系将是多对多的。
我已经成功添加了角色列表,但是当我按下保存时,我得到了空引用的异常。
这是我的代码:

首先是自定义视图:

namespace UserMangment.ViewModel
{
    public class RolesViewMode
    {
        public tab_OnlineUsers OnlineUsers { get; set; }
        public IEnumerable<SelectListItem> AllRolesnames { get; set; }

        private List<string> _selectedRolesname;


        public List<string> SelectedRoleTags
        {
            get
            {
                if (_selectedRolesname == null)
                {
                    _selectedRolesname = OnlineUsers.tab_OnlineRoles.Select(m => m.Id).ToList();
                }
                return _selectedRolesname;
            }
            set { _selectedRolesname = value; }
        }


    }
}

然后是控制器:

namespace ELVIRA_UserMangment.Controllers
{
    public class OnlineUsersController : Controller
    {
        private Entities db = new Entities();

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

        // GET: OnlineUsers/Details/5
        public ActionResult Details(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            tab_OnlineUsers tab_OnlineUsers = db.tab_OnlineUsers.Find(id);
            if (tab_OnlineUsers == null)
            {
                return HttpNotFound();
            }
            return View(tab_OnlineUsers);
        }

        // GET: OnlineUsers/Create
        public ActionResult Create()
        {
            var RolesViewmode = new RolesViewMode
            {
                OnlineUsers = db.tab_OnlineUsers.Create(),
            };
            if (RolesViewmode.OnlineUsers == null)
                return HttpNotFound();

            var allrolles = db.tab_OnlineRoles.ToList();
            RolesViewmode.AllRolesnames = allrolles.Select(o => new SelectListItem
            {
                Text = o.Name,
                Value = o.Id.ToString()
            });
            return View(RolesViewmode);
        }

        // POST: OnlineUsers/Create
        // Aktivieren Sie zum Schutz vor übermäßigem Senden von Angriffen die spezifischen Eigenschaften, mit denen eine Bindung erfolgen soll. Weitere Informationen 
        // finden Sie unter http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Email,EmailConfirmed,PasswordHash,SecurityStamp,PhoneNumber,PhoneNumberConfirmed,TwoFactorEnabled,LockoutEndDateUtc,LockoutEnabled,AccessFailedCount,UserName")] RolesViewMode tab_OnlineUsers)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    db.tab_OnlineUsers.Add(tab_OnlineUsers.OnlineUsers);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                catch(DbEntityValidationException e)
                {
                    Console.WriteLine(e);
                }

            }

            return View(tab_OnlineUsers);
        }

        // GET: OnlineUsers/Edit/5
        public ActionResult Edit(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var RolesViewmode = new RolesViewMode
            {
                OnlineUsers = db.tab_OnlineUsers.Include(i => i.tab_OnlineRoles).First(i => i.Id == id),
            };
            if (RolesViewmode.OnlineUsers == null)
                return HttpNotFound();

            var allrolles = db.tab_OnlineRoles.ToList();
            RolesViewmode.AllRolesnames = allrolles.Select(o => new SelectListItem
            {
                Text = o.Name,
                Value = o.Id.ToString()
            });

            tab_OnlineUsers tab_OnlineUsers = db.tab_OnlineUsers.Find(id);
            if (tab_OnlineUsers == null)
            {
                return HttpNotFound();
            }
            return View(RolesViewmode);
        }

        // POST: OnlineUsers/Edit/5
        // Aktivieren Sie zum Schutz vor übermäßigem Senden von Angriffen die spezifischen Eigenschaften, mit denen eine Bindung erfolgen soll. Weitere Informationen 
        // finden Sie unter http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Email,EmailConfirmed,PasswordHash,SecurityStamp,PhoneNumber,PhoneNumberConfirmed,TwoFactorEnabled,LockoutEndDateUtc,LockoutEnabled,AccessFailedCount,UserName")] tab_OnlineUsers tab_OnlineUsers)
        {
            if (ModelState.IsValid)
            {
                db.Entry(tab_OnlineUsers).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(tab_OnlineUsers);
        }

最后是创建视图:

@model UserMangment.ViewModel.RolesViewMode

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


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

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

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

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

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

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

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

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

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

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

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

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

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

        <div class="form-group">
            @Html.LabelFor(model => model.AllRolesnames, "Roles Name", new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.ListBoxFor(m => m.SelectedRoleTags, Model.AllRolesnames)
            </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>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>


}

所以这段代码成功带入列表,但是将这些信息保存到我的数据库中时出错。

【问题讨论】:

  • 为什么这个微不足道的修订?唯一能显着改善您的问题的是详细说明“存在错误”。

标签: asp.net-mvc ado.net entity-framework-6


【解决方案1】:

让我向您探索一种解决多对多关系问题的技术。 当您遇到数据库中的多对多关系时,您应该为数据库中的两个表创建一个查找表,例如:

如果您有角色和用户表(如果有多个角色分配给用户),那么您应该为这项工作制作一个查找表,在其中保存 RoleId 和 UserId(Id、RoleId、UserId 等任何字段)你想添加)..

每当角色被分配给用户时,您都应该在该表中输入一个条目。

可能有更多可能的解决方案,但每当我遇到多对多关系问题时,我都会这样做..

谢谢,

希望这会有所帮助...

【讨论】:

  • 如果您已经使用过实体框架,您会看到在代码中调用表格后,查找表将消失,您将拥有多对多关系
  • 对不起,你可能误会了我说他们应该是第三个表,其中包含 RoleId 和 UserId 作为外键。之后实际发生的是角色和用户之间的关系将打破角色和可查找表之间的一对多以及用户和可查找表之间的一对多。它在 EF 中对我有用,每次我面对多对多关系时我都会这样做。可能会帮助你 Bilal
  • 谢谢,但正如我已经说过的那样,即使你在中间用实体调用它后在中间制作这个一对多表,它也会消失
  • 不用担心,但奇怪的是,表或实体怎么会消失……这太奇怪了……你在创建查找表后删除了用户和角色的关系吗?问以防万一
  • 这是完全正常的,如果你在使用 mvc 之前你会理解我的问题codeproject.com/Articles/702890/…
猜你喜欢
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多