天天看點

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's Web Platform & Tools Content Team.

在上一次的課程中,你已經學習了如何顯示關聯的資料,我們将要更新關聯的資料。大多數情況下,可能就是更新表的外鍵字段。對于多對多的關系來說,由于 EF 并沒有直接将表與表之間的連接配接關系暴露出來,你就必須通過顯式對相關的導航屬性進行添加或者删除實體來完成。

下面的截圖展示了我們馬上要完成的工作。

當新的課程實體建立的時候,必須包含相關的 Department。為了達到這個目的,腳手架建立的代碼,包括建立和編輯的控制器以及視圖,都包含了對 Department 的下拉清單的支援。下拉清單設定 Course.DepartmentId 外鍵屬性,這對于 EF 通過 Department 導航屬性來加載 Department 實體來說是必須的。下面将要對腳手架生成的代碼進行一些小的改動,增加錯誤的處理以及對清單内容進行排序。

打開 CourseController.cs, 删除原來的 Edit 和 Create 方法,使用下面的代碼替換它們。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

PopulateDepartmentsDropDownList 方法擷取經過對 Name 進行排序的 Department,然後建立用于下拉清單的 SelectList 集合,通過 ViewBag 傳遞到視圖中。這個方法包含一個參數,允許調用方可選地傳遞一個初始選中項目的值。

HttpGet Create 方法調用沒有設定選中項的 PopulateDepartmentsDropDownList 方法,因為對于新建立的課程來說,還沒有确定歸屬的系。

HttpGet Edit 方法則設定了目前選中的項目,基于目前被編輯課程的 DepartmentId。

對于 Create 和 Edit 的 HttpPost 方法來說,在錯誤資訊處理之後,都包含了設定目前選中項目的代碼。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

代碼用來保證即使在顯示錯誤的頁面上,也會保持選中的項目。

在 Views\Course\Create.cshtml, 在 Title 之前增加一個新的字段,允許使用者輸入課程編号。想之前示範的那樣,腳手架沒有生成主鍵字段,因為主鍵字段對使用者沒有意義。是以需要添加以便使用者能夠輸入這個值。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

運作 Create 頁面 ( 在課程的 Index 頁面,點選 Create New  ),然後輸入新的課程。

點選 Create,在 Index 中應該可以看到包含新建立課程的清單。系的名稱通過導航屬性擷取到,顯示的資料是正确的。

運作編輯頁面 ( 在課程的 Index 頁面中在某個課程上選擇 Edit )

修改一些資料,然後點選 Save,可以看到更新之後的課程資料。

在修改教師資訊的時候,我們希望也能夠修改教師的辦公室配置設定。教師實體 Instructor 和辦公室配置設定 OfficeAssignment存在一對一或者一對零的關系,這意味着你必須處理如下的狀态:

如果教師原來存在一個辦公室配置設定,但是使用者删除了它,那麼,你必須移除并且删除這個辦公室配置設定 OfficeAssignment 實體。

如果教師原來沒有辦公室配置設定,但是使用者輸入了一個,你必須建立一個新的辦公室配置設定。

如果使用者修改了原來的辦公室配置設定,你必須修改目前的辦公配置設定 OfficeAssignment 實體。

打開 InstructorController.cs,看一下 HttpGet Edit 方法。

腳手架生成的代碼不是我們希望的,它生成了一個下拉清單,但是我們希望是文本框,将這個方法使用下面的代碼替換掉。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

代碼中删除了 ViewBag 語句,增加了使用預先加載的相關 OfficeAssignment 和 Course 實體 ( 現在還不需要課程實體,一會就會用到 )。由于 Find 方法不能使用預先加載,是以這裡使用 Where 和 Single 方法來擷取教師。

将 HttpPost 的 Edit 方法使用下面的代碼替換,這裡處理了 OfficeAssignment 更新。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

代碼中處理了如下的内容:

從資料庫中擷取了教師 Instructor 實體,并且預先加載了相關的的辦公室配置設定 OfficeAssignment 和課程 Course 導航屬性。如同在 HttpGet 的 Edit 方法一樣。

使用通過模型綁定擷取的資料,更新 Instructor 實體,除了課程 Course 導航屬性之外。

( 第二和第三個參數在屬性名的前面沒有字首,而且沒有被包含的屬性清單 ),如果驗證失敗, TryUpdateModel 方法傳回 false,程式将直接轉到方法最後的 return View 語句。

如果辦公位置為空,設定 Instructor.OfficeAssignment 屬性為 null,在 OfficeAssignment 表相關的行将會被删除。

将修改儲存到資料庫中。

在 Views\Instructor\Edit.cshtml, 在 Hire Date 字段的 div 元素之後,增加新的字段來編輯辦公位置。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

運作頁面 ( 選中教師 Instructors ,點選某個教師的 Edit 連結 )

修改辦公室位置的值,然後儲存 Save。

新的辦公位置出現在 Index 頁面上,打開資料庫中的 OfficeAssgnment 表,可以看到表中的資料行。

運作編輯頁面,将辦公位置 Office Location 清除掉,然後儲存 Save。在 Index 頁面上辦公位置将顯示為空白,在表中的行被删除了。

教師可以教授任意數量的課程。現在你需要擴充教師的編輯頁面,增加通過一系列複選框配置設定可能的能力,如下所示。

在課程 Course 和教師 Instructor 之間存在多對多的關系,這意味着你不需要直接通路表之間的關聯。而是通過增加或者删除 Instructor. Course 實體來完成。

在 UI 界面上,與教師相關的課程被顯示為一組複選框,在資料庫中的每一門課程都有一個對應的複選框,教師目前教授的課程對應的複選框處于被選中狀态。使用者可以通過選中或者取消選中來改變教師教授的課程。如果課程的數量巨大,你可能需要采取其他的方式來顯示這些資料,但是你可以使用類似的方式來控制導航屬性以便建立和删除關系。

為了為視圖提供複選框資料,你需要使用視圖模型 ViewModel,在 ViewModels 檔案夾中建立 AssignedCourseData.cs,使用下面的代碼替換生成的代碼。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

在 InstructorController.cs 中,找到 HttpGet Edit 方法,調用通過視圖模型為視圖中複選框提供資料的新方法,如下所示。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

新建立的方法中,讀取所有的課程實體,加載到視圖模型中,對于每一個課程,檢查這個課程是否存在于教師實體的 Courses 導航集合屬性中。為了更加有效地周遊教師講授的課程,将教師講授的課程通過 HashSet 集合處理,課程中教師講授的課程的 Assigned 屬性被賦予 true。在視圖中通過這個屬性來判斷複選框是否顯示為選中狀态。最後,這個集合通過 ViewBag 傳遞到視圖中。

然後,增加當使用者點選 Save 後執行的代碼。将 HttpPost 中的 Edit 方法使用下面的代碼替換掉,這裡通過調用一個新的方法将教師 Instructor 的導航屬性 Courses 更新。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

如果沒有複選框被選中,在 UpdateInstructorCourse 方法中,使用一個空的集合來初始化 Courses 導航屬性。

然後,代碼周遊資料庫中所有的課程,如果課程的複選框被選中了,但是沒有包含在教師 Insturctor 的 Courses 集合中。這個課程将會被加入到導航屬性集合中。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

如果課程沒有被選中,但是在教師的導航屬性 Courses 集合中,就從集合屬性中删除掉。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

在 Views\Instructor\Edit.cshtml 中,在 OfficeAssignment 區域的 div 之後,增加一個 Courses 區域,通過一組複選框來顯示課程的狀态。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

代碼建立一個 HTML 的三清單格,每一列中顯示課程的标題和編号,後面跟着一個複選框。複選框的名稱是相同的 ( “selectedCourses” ),這樣在模型綁定的時候就會被連接配接成一組。複選框的 value 屬性設定為 CourseID。當送出頁面的時候,選中的複選框代表的 CourseID 将以數組的形式傳遞給控制器。

在複選框被初始化的時候,選中課程對應的複選框的 checked 屬性被設定為選中狀态。

在修改了課程狀态之後,當回到 Index 頁面的時候,需要驗證這些修改。是以,需要在頁面的表格中增加一列,在這裡不需要使用 ViewBag,因為需要的資訊已經通過教師實體 Instructor 的導航屬性 Courses 傳遞到頁面了。

在 Views\Instuctor\Index.cshtml 中,在 <th>Office</th> 之後,增加一個 <th>Course</th> 的标題列,如下所示。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

然後,在辦公位置的單元格之後增加一個詳細内容的單元格。

Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定
Contoso 大學 - 6 – 更新關聯資料6-1  定制課程的建立和編輯頁面6-2  增加教師的編輯頁面6-3  在教師編輯頁面增加課程配置設定

運作 Instructor 的 Index 頁面,檢查教師的授課情況。

點選 Edit 檢視編輯頁面。

修改一些課程的授課情況,然後儲存 Save,修改的結果在 Index 頁面中可以看到。

你已經完成了修改關聯資料的工作。通過目前的課程你已經可以完成增、删、改、查所有的操作,但是還沒有考慮并發問題。下一次我們将探讨并發問題,展示處理并發的方式,然後對已經完成的實體的增、删、改、查的代碼增加并發處理。