简体   繁体   English

从MVC C#中的单个视图对不同表中的多个相关记录进行CRUD操作

[英]CRUD operations for multiple related records in different tables from single view in MVC C#

I was hoping I could get some assistance on this functionality I am trying to achieve. 我希望我可以在此功能上得到一些帮助。 I have searched, but i do not seem to be able to translate the examples/tutorials I have found to make it work in my own code. 我进行了搜索,但似乎无法翻译我发现的示例/教程,以使其能够在自己的代码中运行。

For brevity, let's say I have 2 Models with a one to many relationship between the two. 为简便起见,假设我有2个模型,两者之间存在一对多的关系。 Let's say it is parents and children. 假设是父母和孩子。 One parent can have zero or many children. 一位父母可以有零个或多个孩子。 Each child can only have 1 parent: 每个孩子只能有1个父母:

namespace MyApp.Models
{
  public partial class Parent 
    {
      [Key]
      public int parent_id { get; set; }
      public string parent_name { get; set; }
      public string parent_address { get; set; }
      public ICollection<Child> Child { get; set; }
    }
  public partial class Child { get; set; }
    {
      [Key]
      public int child_id { get; set; }
      public int parent_id { get; set; }
      public string child_name { get; set; }
      public string child_allergies { get; set; }
      public virtual Parent parent { get; set; } 
    }
}

Entity created the tables in the database properly, assigning primary/foreign keys where they needed to be. 实体在数据库中正确创建了表,并在需要的地方分配了主键/外键。

I put the common fields in a viewmodel to render them in my view: 我将公共字段放在视图模型中以在我的视图中呈现它们:

using MyApp.Models;
namespace MyApp.ViewModels
{
  public class ParentChildViewModel
    {
      public int parent_id { get; set; }
      public string parent_name { get; set; }
      public string parent_address { get; set; }
      public string child_name { get; set; }
      public string child_allergies { get; set; }
    }
}

I have my view written as below: 我的看法如下:

@model MyApp.ViewModels.ParentChildViewModel
@using (Html.BeginForm()) 
{
  <div>
    @Html.LabelFor(model => model.parent_name)
    @Html.EditorFor(model => model.parent_name)
  </div>

  <div>
    @Html.LabelFor(model => model.parent_address)
    @Html.EditorFor(model => model.parent_address)
  </div>

  <table id="child_table">
    @{ Html.RenderPartial("_children"); }
  </table>

  <div>
  <button id="add">Add Child</button>
  <button id="rem">Remove Child</button>
  </div>

  <div>
  <input type="submit" value="Create" />
  </div>
}
<script type="text/javascript">
    $("#add").click(function () {
      $.ajax({
        url: "@Url.Action("BlankChRow")",
        cache: false,
        success: function (html) {
          $("#child_table").append(html);
        }
      });
    return false;
    });
    $("#rem").click(function () {
      $("#child_table tbody tr:last")
        .remove();
      return false;
    });
</script>

I created a partial view for the child so I can repeat those: 我为孩子创建了局部视图,因此我可以重复这些操作:

@model MyApp.ViewModels.ParentChildViewModel
@using (Html.BeginCollectionItem("children"))
{
<tr>
  <td>
  <div>
    @Html.LabelFor(model => model.child_name)
    @Html.EditorFor(model => model.child_name)
  </div>
  </td>

  <td>
  <div>
    @Html.LabelFor(model => model.child_allergies)
    @Html.EditorFor(model => model.child_allergies)
  </div>
  </td>
</tr>
}

Then, in my controller (this is where I am stuck): 然后,在我的控制器中(这就是我遇到的问题):

private ApplicationDbContext db = new ApplicationDbContext();

public ActionResult BlankChRow()
{
  return PartialView("_children");
}

public ActionResult Create()
{
  return View(new ParentChildViewModel());
}

[HttpPost]
public ActionResult Create(ParentChildViewModel pcvm)
{
  var parent = new Parent()
  {
    parent_id = pcvm.parent_id,
    parent_name = pcvm.parent_name,
    parent_address = pcvm.parent_address
  };
  var child = new Child()
  {
    parent_id = pcvm.parent_id,
    child_name = pcvm.child_name,
    child_allergies = pcvm.child_allergies
  };
  if (ModelState.IsValid)
  {
    db.Parent.Add(parent);
    db.Child.Add(child);
    db.SaveChanges();
    return RedirectToAction("Index");
  }
return View(pcvm);
}

I have experimented a few different ways of doing this... but I am unable to get this working the way I would like. 我已经尝试了几种不同的方法来进行此操作...但是我无法按照我想要的方式进行操作。 Ideally, the View can be brought up, and while they enter the Parent's data, they could add one or many children. 理想情况下,可以调出视图,并且当他们输入父级数据时,他们可以添加一个或多个子级。 The children that are added would each be their own record in the Child table/entity while having the appropriate parent_id. 被添加的子项将在拥有适当的parent_id的情况下分别成为子表/实体中的记录。

Any help is appreciated. 任何帮助表示赞赏。

I see that you want to generate a list of children for a given parent but your viewmodel doesn't look so. 我看到您想为给定的父代生成子代列表,但是您的viewmodel看起来不是这样。

using MyApp.Models;
namespace MyApp.ViewModels
{
  public class ParentChildViewModel
    {
      public int parent_id { get; set; }
      public string parent_name { get; set; }
      public string parent_address { get; set; }
      public string child_name { get; set; }
      public string child_allergies { get; set; }
    }
}

Try a viewmodel with a list of children. 尝试一个带有孩子列表的视图模型。 Something like this : 像这样的东西:

using MyApp.Models;
namespace MyApp.ViewModels
{
  public class ParentChildViewModel
    {
      public int parent_id { get; set; }
      public string parent_name { get; set; }
      public string parent_address { get; set; }
      public IEnumerable<Child> children { get; set; }
    }
}

I'm supposing here that you just want to iterate over the list. 我在这里假设您只想遍历列表。 That's why I use the IEnumerable interface instead of the IList interface. 这就是为什么我使用IEnumerable接口而不是IList接口的原因。

To add a child in the list, you could call the "Create" function of your controller and pass the parent_id of the new child. 要在列表中添加子项,可以调用控制器的“创建”功能并传递新子项的parent_id。 In your controller you can therefore create a new child for a given parent in the database using your application context. 因此,您可以在控制器中使用应用程序上下文为数据库中的给定父级创建一个新子级。

Once the database transaction done, you can create a new ParentChildViewModel and fulfill it with the corresponding children and return it to the view. 数据库事务完成后,您可以创建一个新的ParentChildViewModel并将其与相应的子代一起实现,并将其返回到视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM