OpenAccess快速入門13
OpenAccess 快速入門將協助我們熟悉 OpenAccess,第十三篇說明如何透過 OpenAccess 刪除資料的同時,刪除關聯的資料。
PS. 老婆待產中,鐵人賽還是不能斷,在待產室中寫文貼文~~~ 老婆加油~~~
這篇是快速入門系列的最後一篇,要說明的是如何在刪除 Master 資料時,一併將關聯的明細資料刪除。
一開始要做一點準備工作,首先,在 ProductMgmt 類別裡,把查詢一筆產品資料的程式碼重構,抽成獨立的函式:
Public Function GetProduct(ByVal Id As Long) As Products
Dim product = (From x In cxt.Products
Where x.PRODUCTID = Id
Select x).FirstOrDefault()
Return product
End Function
請注意,要把存取範圍設定為 Public,以利單元測試和其他專案調用。再來,我們確認一下資料庫中,目前「進擊類」的類別和所關聯的產品資料:
準備工作完成後,我們在 Model 專案中建立一個 Categories 類別,撰寫以下刪除作業所需的程式碼:
Public Class CategoriesMgmt
Private cxt As SecondModel
Public Sub New()
cxt = New SecondModel()
End Sub
Public Function GetAttackCategories() As IList(Of Categories)
Dim query = From x In cxt.Categories
Where x.CATEGORYNAME = "進擊類"
Select x
Return query.ToList()
End Function
Public Function DeleteCategory(id As Long) As Boolean
Dim category = GetCategory(id)
If category Is Nothing Then
Throw New System.NullReferenceException(String.Format("查無類別編號:{0} 的資料。", id))
End If
cxt.Delete(category)
cxt.SaveChanges()
Return True
End Function
Private Function GetCategory(ByVal id As Long) As Categories
Dim category = (From x In cxt.Categories
Where x.CATEGORYID = id
Select x).FirstOrDefault()
Return category
End Function
End Class
和前一篇 ProductMgmt 類別的相同,主要刪除作業由 DeleteCategory() 函式處理,GetAttackCategories() 函式是之後要給頁面查詢使用的函式。現在我們加入單元測試來驗證程式是否可正確完成刪除類別及所屬產品資料的動作:
<TestMethod()> _
Public Sub DeleteCategoryTest()
Dim target = New CategoriesMgmt()
Dim createBo = New CreateEntities()
Dim productBo = New ProductsMgmt()
Dim tempProduct = createBo.CreateProductAndCategory()
Dim expected As Boolean = True
Dim actual = target.DeleteCategory(tempProduct.CATEGORYID)
Assert.AreEqual(expected, actual)
Assert.IsNull(productBo.GetProduct(tempProduct.CATEGORYID))
End Sub
單元測試失敗了!為什麼呢?看看錯誤訊息:
重點是:
ORA-01407: cannot update ("LEO"."PRODUCTS"."CATEGORYID") to NULL
這就表示,目前刪除 Categories 的資料時,OpenAccess 會把關聯的 Products 資料 CategoriesId 屬性設為 Null,但是因為這個欄位是不允許 Null,所以執行更新時會發生 Exception。
實務上,刪除 Master 資料時,對於關聯的明細資料有四種處理方式:
上述把 CategoriesId 設定為 Null,就屬於第二種方式,不過在我們這個案例中,明顯不可行,所以我們選擇第一種方式,刪除明細資料,但該如何修改?
很簡單,請開啟 SecondModel 的視覺化設計工具,把 Products 的導覽屬性 Categories 之屬性面版打開,將【Is Dependent】設定為 True:
再執行一次單元測試,成功囉:
因為篇幅太長了,所以頁面的程式碼我就不貼了,基本上,頁面和前一篇雷同,只是同時顯示兩個 Grid,一個是類別,一個是關聯的產品,然後我們在類別的 Grid 中按刪除連結,程式調用 DeleteCategory() 函式將類別和關聯產品刪除,回到頁面上就會看到該類別和關聯的產品資料已經不見了。