2017-07-29 148 views
2

我有一個UserTask模型之間的多對多關係。我想在創建新任務時將任務分配給用戶。正因爲如此,我創建了UserViewModelCheckBoxView模型。但是現在我可以在編輯用戶表時將任務分配給用戶。我知道我必須改變UserControllerCreate行動,但我不知道如何。ASP.NET MVC 5&Entity Framework多對多關係

這裏是我的代碼:

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Surname { get; set; } 

    public virtual ICollection<UserToTask> UserToTasks { get; set; } 
} 

public class Task 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 

    public virtual ICollection<UserToTask> UserToTasks { get; set; } 
} 

public class UserToTask 
{ 
    public int Id { get; set; } 
    public int UserId { get; set; } 
    public int TaskId { get; set; } 

    public virtual User User { get; set; } 
    public virtual Task Task { get; set; } 
} 

public class CheckBoxViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public bool Checked { get; set; } 
} 

public class UserViewModel 
{ 
    public int UserId { get; set; } 
    public string Name { get; set; } 
    public string Surname { get; set; } 
    public List<CheckBoxViewModel> Tasks { get; set; } 
} 

用戶控制器:

public class UsersController : Controller 
{ 
    private MyModel db = new MyModel(); 

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

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

    // POST: Users/Create 
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see https://go.microsoft.com/fwlink/?LinkId=317598. 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create([Bind(Include = "Id,Name,Surname")] User user) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Users.Add(user); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     return View(user); 
    } 

    // GET: Users/Edit/5 
    public ActionResult Edit(int? id) 
    { 
     if (id == null) 
     { 
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 

     User user = db.Users.Find(id); 

     if (user == null) 
     { 
      return HttpNotFound(); 
     } 

     var result = from a in db.Tasks 
      select new 
      { 
       a.Id, 
       a.Title, 
       Checked = (from ab in db.UserToTasks 
        where (ab.UserId == id) & (ab.TaskId == a.Id) 
        select ab).Any() 
      }; 

     var MyViewModel = new UserViewModel(); 
     MyViewModel.UserId = id.Value; 
     MyViewModel.Name = user.Name; 
     MyViewModel.Surname = user.Surname; 

     var MyCheckBoxList = new List<CheckBoxViewModel>(); 

     foreach (var item in result) 
     { 
      MyCheckBoxList.Add(new CheckBoxViewModel{Id = item.Id, Name = item.Title, Checked = item.Checked}); 
     } 

     MyViewModel.Tasks = MyCheckBoxList; 

     return View(MyViewModel); 
    } 

    // POST: Users/Edit/5 
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see https://go.microsoft.com/fwlink/?LinkId=317598. 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit(UserViewModel user) 
    { 
     if (ModelState.IsValid) 
     { 
      var MyUser = db.Users.Find(user.UserId); 
      MyUser.Name = user.Name; 
      MyUser.Surname = user.Surname; 

      foreach (var item in db.UserToTasks) 
      { 
       if (item.UserId == user.UserId) 
       { 
        db.Entry(item).State = EntityState.Deleted; 
       } 
      } 

      foreach (var item in user.Tasks) 
      { 
       if (item.Checked) 
       { 
        db.UserToTasks.Add(new UserToTask() {UserId = user.UserId, TaskId = item.Id}); 
       } 
      } 

      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(user); 
    } 
} 

編輯觀點:

@model ItalianCoach.Models.UserViewModel 

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

<div class="form-horizontal"> 
    <h4>User</h4> 
    <hr /> 
    @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
    @Html.HiddenFor(model => model.UserId) 

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

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

    <div class="form-group"> 
     @Html.LabelFor(model => model.Tasks, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @for (int i = 0; i < Model.Tasks.Count(); i++) 
      { 
       @Html.EditorFor(m => m.Tasks[i].Checked) 
       @Html.DisplayFor(m => m.Tasks[i].Name)<br/> 

       @Html.HiddenFor(m => m.Tasks[i].Name) 
       @Html.HiddenFor(m => m.Tasks[i].Id) 
      } 
     </div> 
    </div> 
</div> 
} 
+0

你爲用戶創建了什麼?它看起來不錯。除非你想在創建用戶時分配任務。 –

+0

正如我所提到的,我想在創建用戶時將所有任務都看到併爲此用戶分配任務。目前我可以創建用戶 – muradheydarov

回答

0

你不需要UserToTask類。它們之間的關係應該與對象類本身有關。

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Surname { get; set; } 

    public int TaskId { get; set; } 
    public virtual Task Task { get; set; } 

    public virtual ICollection<Task> Tasks { get; set; } 
} 

public class Task 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
} 

您將TaskId作爲外鍵添加到User類中。每個用戶都有一個任務集合(可能也可能不是空的 - 所以要小心你的構造函數)。

查找特定任務的所有用戶 - 您在用戶上使用數據庫查詢 - >其中TaskId == Task.Id.

您需要整理xaml,控制器等以適應新模型。

+0

您所描述的是帶有隱式鏈接表的多對多模型。但它只是EF支持的多對多模型之一 - OP使用的是另一種模型。既然都有優點和缺點,我不會說這總比其他優先。談到可移植性,EF Core目前僅支持具有明確實體的模型。所以你所建議的並不是非常必要的。也看起來不解決與'創建'控制器操作的OP問題。 –

+0

@IvanStoev是的,你是對的,從數據庫規範化的角度來看,我真的不喜歡像這樣加入對象。是的,我看過創建問題。我現在會刪除它,稍後再回來。 (我正在烹飪)實際上,創建方法對於用戶來說看起來不錯。 –

相關問題