EF學習筆記(八):更新關聯數據
學習筆記主目錄鏈接:ASP.NET MVC5 及 EF6 學習筆記 - (目錄整理)
上一篇鏈接:EF學習筆記(七):讀取關聯數據
本篇原文鏈接:Updating Related Data
本篇主要考慮對於有關聯的數據進行新增、刪除、更新操作;比如Course 、Instructor;
對於Course來說,新增時候必須定義屬於哪個Department,所以在新增、更新操作的時候,必須要用戶選擇Department;
MVC5在選擇基礎控制器及視圖框架的時候,如果選擇EF的操作框架,則會自動帶一部分基礎代碼,比如Course的Create\Edit直接就帶上了Department的下拉列表選擇框;
但是對於一些錯誤情況處理不夠以及沒有做顯示排序,原文做了些調整優化;
public ActionResult Create() { PopulateDepartmentsDropDownList(); return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "CourseID,Title,Credits,DepartmentID")]Course course) { try { if (ModelState.IsValid) { db.Courses.Add(course); db.SaveChanges();return RedirectToAction("Index"); } } catch (RetryLimitExceededException /* dex */) { //Log the error (uncomment dex variable name and add a line here to write a log.) ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); } PopulateDepartmentsDropDownList(course.DepartmentID); return View(course); } public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Course course = db.Courses.Find(id); if (course == null) { return HttpNotFound(); } PopulateDepartmentsDropDownList(course.DepartmentID); return View(course); } [HttpPost, ActionName("Edit")] [ValidateAntiForgeryToken] public ActionResult EditPost(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var courseToUpdate = db.Courses.Find(id); if (TryUpdateModel(courseToUpdate, "", new string[] { "Title", "Credits", "DepartmentID" })) { try { db.SaveChanges(); return RedirectToAction("Index"); } catch (RetryLimitExceededException /* dex */) { //Log the error (uncomment dex variable name and add a line here to write a log. ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); } } PopulateDepartmentsDropDownList(courseToUpdate.DepartmentID); return View(courseToUpdate); } private void PopulateDepartmentsDropDownList(object selectedDepartment = null) { var departmentsQuery = from d in db.Departments orderby d.Name select d; ViewBag.DepartmentID = new SelectList(departmentsQuery, "DepartmentID", "Name", selectedDepartment); }
PopulateDepartmentsDropDownList
方法給視圖傳遞了一個用Name排序過的Department列表;
並且處理了新建的時候 選中的Department為空的情況;
Create、Edit的Post請求中都對異常情況做了處理,並同時在下拉框還保持原先的選擇;
另外,在Create、Edit的視圖中,對於Department的標題也需要從DepartmentID改為Department :
<div class="form-group"> <label class="control-label col-md-2" for="DepartmentID">Department</label> @*@Html.LabelFor(model => model.DepartmentID, "DepartmentID", htmlAttributes: new { @class = "control-label col-md-2" })*@ <div class="col-md-10"> @Html.DropDownList("DepartmentID", null, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.DepartmentID, "", new { @class = "text-danger" }) </div>
</div>
另外,對於Create視圖,EF默認框架建立的視圖會根據主關鍵字段是不是自動列來采用不同的方式;
如果定義為自動增加列,則不需要用戶輸入,由數據庫自增長;
如果定義為非自動增長列,則需要用戶手動,則會提供一個輸入框;
但對於Edit視圖,EF默認框架建立的視圖不會明文顯示主關鍵字段,因為它不知道這個字段到底有沒有顯示意義,它只用一個隱藏字段來包含主關鍵字段數據;
所以要手動增加顯示主關鍵字段,但是就算自己手動增加顯示主關鍵字段,也不可以刪除那個隱藏字段!
@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.CourseID) <div class="form-group"> @Html.LabelFor(model => model.CourseID, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DisplayFor(model => model.CourseID) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" }) </div> </div>
同樣,在Delete、Detail視圖中,需要加入CourseID的顯示:
<dt> @Html.DisplayNameFor(model => model.Department.Name)
</dt>
<dd> @Html.DisplayFor(model => model.Department.Name) </dd> <dt> @Html.DisplayNameFor(model => model.CourseID) </dt> <dd> @Html.DisplayFor(model => model.CourseID) </dd> <dt> @Html.DisplayNameFor(model => model.Title) </dt> <dd> @Html.DisplayFor(model => model.Title) </dd>
Course 修改效果:
EF學習筆記(八):更新關聯數據