在初次使用EF的Database first時,總感覺能迅速的從Data Table 快速將Entity Model快速建立出來,省去以往還要hard code撰寫POCO類別的功夫,但資料表設計隨著開發而更新了幾個版本後,常常發生Model 與 Table對不起來的情況,即便執行了"從資料庫更新模型",不是欄位沒反映出來、就是出現錯誤訊息,常常最後只能選擇全部砍掉重練....
在初次使用EF的Database first時,總感覺能迅速的從Data Table 快速將Entity Model快速建立出來,省去以往還要hard code撰寫POCO類別的功夫,但資料表設計隨著開發而更新了幾個版本後,常常發生Model 與 Table對不起來的情況,即便執行了"從資料庫更新模型",不是欄位沒反映出來、就是出現錯誤訊息,常常最後只能選擇全部砍掉重練。
為了要理解這個問題,我們就先來看一下Entity Framework的設計:
先關注一下圖的左側方,也就是EDM(Entity Data Model)的部份,這邊代表的是ORM的骨髓,也就是POCO Model (Conceptual Model) 與實際Data Table(Storage Model)相關設計與Mapping的設定,在Database First中就是以edmx這個xml檔來表示。如果我們以xml編輯器來開敋,可以看見Storage Models, Conceptual Models 以及其關聯資料(Mappings)均在這個檔案中。
藉由這三個設定區塊可以發現,ORM三者各自被設定在不同的區塊下,而當以DB First執行"從資料庫更新模型",實際上的行為是
”藉由外部DB更新EDM中的Storage Model”
”藉由外部DB更新EDM中的Storage Model”
”藉由外部DB更新EDM中的Storage Model” <--很重要, 所以要說三次
如此,針對這樣的設計我們可以提出以下問題:
- 如果在edmx中刪除了某個Property但這個欄位實際還是存在於Database中,然後在edmx中執行"從資料庫更新模型"後, edmx會不會在次反應出這個欄位?
- 如果在Database中刪除了某個Column,在edmx中執行"從資料庫更新模型"後,edmx會不會也一併刪除這個欄位?
- 如果在edmx中更改了某個Property名稱,然後在edmx中執行"從資料庫更新模型"後, edmx會不會再次把這個Property改為Database中的欄位名稱?
- 如果在Database中更改了某個欄位名稱,然後在edmx中執行"從資料庫更新模型"後, edmx會不會再次把對應Property改為Database中的欄位名稱?
- 如果在edmx新增了一個Property,接著在edmx中執行"從資料庫更新模型"後,新的Property在edmx中會不會消失?
- 如果在Database新增了一個欄位,接著在edmx中執行"從資料庫更新模型"後,新的column會不會產生一個property?
本來想要一個一個貼圖說明的,但避免文章過於冗長,以下列出解答:
- 不會,更新的是Storage Model,而在你的edmx記錄的Storage Model中,此欄位還是存在。
- 會反應出這個現象,接著得到一個Error 11009: Property 'XXX' is not mapped的Error Message。
- 不會,你改的是Conceptual Model上的Property,並沒有動到Storage Model,而實際上的data table也沒有變更,由藉此可以達到Property對應到不同名的Column。當我們查看Mapping Detail時,可以發現Model與Data Table對應的真實關係。
-
不會,EF沒辦法判別出這是一個rename的情境,所以在你的Model中會留著rename前的property名稱,與一個新的Property名稱。這時候你可以開啟Table Mapping來調整,將正確的property對應到對的table column上,而將多除的一個property刪掉。
-
不會,更新的是Storage Model,並不是你手動異動的Conceptual Model,所以你手動加的欄位還是會存在,只是會得到一個Error 11009: Property 'XXX' is not mapped的錯誤訊息。
-
會,edmx中的Storage Model並沒有這個欄位,EF便會把這個欄位加入storage model, 由於是新增動作,Conceptual Model及mapping部份也會一併建立。
其實,在了解了Entity Data Model的設計後,就可以知道你的修改動作會造成什麼影響,Conceptual Model或Storage Model會不會一併更新,如此也會知道何時該進行手動調整。
參考:
http://www.entityframeworktutorial.net/EntityFramework-Architecture.aspx