2016-08-22 62 views
-1

我見過很多關於MVC的教程。但直到現在還沒有明確的答案如何處理多對多的關係,導致許多這些教程結果都有相同的錯誤。
我正在使用數據庫的第一種方法,我的應用程序應該添加用戶,同時添加用戶我應該有一個角色列表,我可以將這些角色添加到此用戶或相反,我可以有用戶列表和編輯角色和作爲我們知道何時將數據庫添加到ado.net中,因此關係將是多對多的。
我已經成功添加角色的列表,但是當我按下保存時,我得到了空引用的異常。
這是我的代碼:
在MVC中處理多對多asp.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> 


} 

所以此代碼成功列入清單但是,將這些信息保存到我的數據庫時出錯。

回答

1

讓我來探討一下你的一個技巧來解決多關係問題。 當過你面對多對多的關係數據庫,你應該做一個查找表中的數據庫就像兩個表:

如果你有一個角色和用戶表(如果不止一個角色分配給用戶),所以你應該爲這項工作做一個查找表,你可以在其中保存RoleId和UserId(Id,RoleId,UserId等等你想要添加的任何字段)。

而且每當角色被分配給用戶,你應該在該表中創建一個條目。

有可能是針對更可能的解決方案這個我在做什麼,每當我面對的多對多關係艦問題..

感謝,

希望這將有助於...

+0

如果你已經使用了實體框架工作,你會看到在調用代碼中的表格後,查找表就會消失,並且你將會有多對多的關係 – BilalMarzouk

+0

對不起,也許你誤會了我說他們應該是第三個表其中包含RoleId和UserId作爲外鍵。實際發生的事情是,角色和用戶之間的關係將在角色和可查找**之間突破一對多關係**並且在用戶和可查找**之間一對多關係。它在EF工作,我每次面對多對多的關係時都會這樣做。 可能是它幫助你Bilal –

+0

謝謝,但正如我已經說過,在這裏沒有布拉克表,即使你使這個對多個表在中間的多個表後,它與實體調用它會消失 – BilalMarzouk