关于EF4.0中多对多关系的添加与修改的解决方案(MVC)

首先在此声明一下,我不是这方面的高手,也是一个初学者,如果文章中出现不对的地方还请诸位多多指正。
进入正题。
首先我们在数据库中建三个表
新闻表:News
分类表:Categories
新闻与分类的关系表:NewsInCategories
关系如下:

先在数据库中预先添加几个分类:
现在开始添加新闻:
以下是页面代码:

  1. @model MvcRelationShipTest.Models.News
  2. @{
  3.     ViewBag.Title = "Create";
  4. }
  5. <h2>
  6.     Create</h2>
  7. <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
  8. <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
  9. @using (Html.BeginForm())
  10. {
  11.     @Html.ValidationSummary(true)
  12.     <fieldset>
  13.         <legend>News</legend>
  14.         <div class="editor-label">
  15.             @Html.LabelFor(model => model.Title)
  16.         </div>
  17.         <div class="editor-field">
  18.             @Html.EditorFor(model => model.Title)
  19.             @Html.ValidationMessageFor(model => model.Title)
  20.         </div>
  21.         <div class="editor-label">
  22.             @Html.LabelFor(model => model.Content)
  23.         </div>
  24.         <div class="editor-field">
  25.             @Html.EditorFor(model => model.Content)
  26.             @Html.ValidationMessageFor(model => model.Content)
  27.         </div>
  28.         <div class="editor-label">
  29.             @Html.LabelFor(model => model.AddTime)
  30.         </div>
  31.         <div class="editor-field">
  32.             @Html.TextBox("AddTime", DateTime.Now)
  33.             @Html.ValidationMessageFor(model => model.AddTime)
  34.         </div>
  35.         <div class="editor-label">
  36.             @Html.Label("分类")
  37.         </div>
  38.         <div class="editor-field">
  39.             @*Html.CheckBoxFor(Model => Model.Categories)*@
  40.             @{Html.RenderAction("ChcekList", "Categories");}
  41.         </div>
  42.         <p>
  43.             <input type="submit" value="添加" />
  44.         </p>
  45.     </fieldset>
  46. }
  47. <div>
  48.     @Html.ActionLink("Back to List", "Index")
  49. </div>

CheckList的View:

  1. @model IEnumerable<MvcRelationShipTest.Models.Categories>
  2. <ul>
  3.     @foreach (var item in Model)
  4.     {
  5.         <li>
  6.             <label for="@item.Id">@item.Name</label>
  7.             <input type="checkbox" name="CategoryId" value="@item.Id" id="@item.Id"/>
  8.         </li>
  9.     }
  10. </ul>

添加页面没什么特别的。

News的Control部分:

[csharp] view plain copy

  1. //GET
  2. public ActionResult Create()
  3. {
  4.     return View();
  5. }
  6. [HttpPost]
  7. public ActionResult Create(Models.News model)
  8. {
  9.     try
  10.     {
  11.         var t = Request["CategoryId"];//获取选中的分类ID格式为("1,2,3”)不包含括号。
  12.         using (var db = new dbContent())
  13.         {
  14.             if (t != null)
  15.             {
  16.                 List<Int32> idlist = StringToIntList(t);//将传来的分类ID转成List<int>
  17.                 var cate = db.Categories.Where(p => idlist.Contains(p.Id));
  18.                 foreach (var item in cate)
  19.                 {
  20.                     model.Categories.Add(item);//给新闻添加分类
  21.                 }
  22.             }
  23.             db.News.AddObject(model);
  24.             db.SaveChanges();
  25.             return RedirectToAction("Index");
  26.         }
  27.     }
  28.     catch (Exception ex)
  29.     {
  30.         var y = ex.InnerException;
  31.         return View(model);
  32.     }
  33. }


以上是添加新闻的页面代码。
现在修改新闻
Edit View的代码:

  1. @model MvcRelationShipTest.Models.News
  2. @{
  3.     ViewBag.Title = "Edit";
  4. }
  5. <h2>
  6.     Edit</h2>
  7. <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
  8. <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
  9. @using (Html.BeginForm())
  10. {
  11.     @Html.ValidationSummary(true)
  12.     <fieldset>
  13.         <legend>News</legend>
  14.         @Html.HiddenFor(model => model.Id)
  15.         <div class="editor-label">
  16.             @Html.LabelFor(model => model.Title)
  17.         </div>
  18.         <div class="editor-field">
  19.             @Html.EditorFor(model => model.Title)
  20.             @Html.ValidationMessageFor(model => model.Title)
  21.         </div>
  22.         <div class="editor-label">
  23.             @Html.LabelFor(model => model.Content)
  24.         </div>
  25.         <div class="editor-field">
  26.             @Html.EditorFor(model => model.Content)
  27.             @Html.ValidationMessageFor(model => model.Content)
  28.         </div>
  29.         <div class="editor-label">
  30.             @Html.LabelFor(model => model.AddTime)
  31.         </div>
  32.         <div class="editor-field">
  33.             @Html.EditorFor(model => model.AddTime)
  34.             @Html.ValidationMessageFor(model => model.AddTime)
  35.         </div>
  36.         <div class="editor-label">
  37.             @Html.Label("分类")
  38.         </div>
  39.         <div class="editor-field">
  40.             <ul>
  41.                 @*绑定分类,如果是以选择的 则加载时让他的状态为checked*@
  42.                 @{List<MvcRelationShipTest.Models.Categories> list = (ViewBag.Categories as List<MvcRelationShipTest.Models.Categories>);
  43.                   foreach (var item in list)
  44.                   {
  45.                     <li>
  46.                         <label for="@item.Id">@item.Name</label>
  47.                         @if (Model.Categories.Contains(item))
  48.                         {
  49.                             <input type="checkbox" name="CategoryId" value="@item.Id" id="@item.Id" checked="checked" />
  50.                         }
  51.                         else
  52.                         {
  53.                             <input type="checkbox" name="CategoryId" value="@item.Id" id="@item.Id" />
  54.                         }
  55.                     </li>
  56.                   }
  57.                 }
  58.             </ul>
  59.             @*Action("ChcekList", "Categories")*@
  60.         </div>
  61.         <p>
  62.             <input type="submit" value="Save" />
  63.         </p>
  64.     </fieldset>
  65. }
  66. <div>
  67.     @Html.ActionLink("Back to List", "Index")
  68. </div>


Controller部分的代码:

[csharp] view plain copy

  1. public ActionResult Edit(int id)
  2.         {
  3.             var db = new dbContent();
  4.             ViewBag.Categories = db.Categories.ToList();
  5.             var model = db.News.Where(n => n.Id == id).FirstOrDefault();
  6.             return View(model);
  7.         }
  8.         [HttpPost]
  9.         public ActionResult Edit(int id, Models.News model)
  10.         {
  11.             try
  12.             {
  13.                 model.Id = id;
  14.                 var t = Request["CategoryId"];
  15.                 using (var db = new dbContent())
  16.                 {
  17.                     if (t != null)
  18.                     {
  19.                         List<Int32> idlist = StringToIntList(t);
  20.                         //新的分类
  21.                         var cate = db.Categories.Where(p => idlist.Contains(p.Id)).ToList();
  22.                         //原来的分类
  23.                         var olist = model.Categories.AsQueryable();
  24.                         //要删除的分类
  25.                         var dlist = olist.Where(p => !cate.Contains(p)).ToList();
  26.                         //要添加的分类
  27.                         var alist = cate.Where(p => !olist.Contains(p)).ToList();
  28.                         foreach (var item in dlist)
  29.                         {
  30.                             model.Categories.Remove(item);
  31.                         }
  32.                         foreach (var item in alist)
  33.                         {
  34.                             model.Categories.Add(item);
  35.                         }
  36.                     }
  37.                     else
  38.                     {
  39.                         model.Categories.Clear();
  40.                     }
  41.                     db.ObjectStateManager.ChangeObjectState(model, EntityState.Modified);
  42.                     db.SaveChanges();
  43.                 }
  44.                 return RedirectToAction("index");
  45.             }
  46.             catch (Exception ex)
  47.             {
  48.                 var t = ex.InnerException;
  49.                 var db = new dbContent();
  50.                 ViewBag.Categories = db.Categories.ToList();
  51.                 return View(model);
  52.             }
  53.         }

好了,修改也完成了。
现在分析一下,其实最关键的就是你要把你选择的分类ID以("1,2,3,4,5,9")的方式传到后台。
后台在根据这个分类ID获取分类,然后添加到新闻中,跟web的处理有点类似。
看一下最后的成果,嘻嘻!

想要demo的朋友请加QQ群:63181865索取。
到此结束。

声明:本站内容来源于原创和互联网,尊重作者版权,转载请注明来源网址,欢迎收藏,谢谢!