2017-07-29 16 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; } 
} 

タスクIDをUserクラスの外部キーとして追加します。各ユーザーには、タスクのコレクションがあります(空でも空でもないので、コンストラクターには注意してください)。

特定のタスクのすべてのユーザーを検索するには、Users - > TaskId == Task.Idのデータベースクエリを使用します。

新しいモデルに合うようにxaml、コントローラなどを並べ替える必要があります。

+0

あなたが何を記述しているかは、暗黙のリンクテーブルを持つ多対多のモデルです。しかし、これはEFでサポートされている可能な多対多のモデルのほんの1つで、OPによって使用されるモデルはもう1つです。両方とも賛否両論があるので、私はこれが常に他のものよりも好ましいとは言いません。また、移植性について言えば、EF Coreは現在、明示的なエンティティを持つモデルのみをサポートしています。だからあなたが示唆していることは強く必要ではありません。また、 'Create'コントローラアクションのOP問題に対処していないようです。 –

+0

@IvanStoevはい、そうです。データベースの正規化の観点から、私はそのようなオブジェクトを結合するのは本当に嫌です。そして、はい、私はCreate問題を見ました。私は今これを削除し、後でそれに戻ってきます。 (私は調理しています)実際には、createメソッドはUserのように見えます。 –

関連する問題