2017-07-29 158 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是的,你是对的,从数据库规范化的角度来看,我真的不喜欢像这样加入对象。是的,我看过创建问题。我现在会删除它,稍后再回来。 (我正在烹饪)实际上,创建方法对于用户来说看起来不错。 –

相关问题