前言
本篇是上一篇EFCore Lazy Loading + Inheritance = 乾凈的資料表 (一) 【獻給處女座的DB First程式猿】 前菜 的續篇。這一篇才是真的為處女座的DB First程式猿準備的正餐。
繼續上一篇的話題,我們希望用EFCore,且繼續使用與邏輯設計的β角偏差很少的資料表結構,徹底不想看到那種“裝飾牆”的效果。
提醒一下,這一部分,屬於有點”走火入魔“的性質。因為是要回過頭來改動類的程式碼(稍微改動邏輯設計)來遷就資料表(物理設計),透過達到平衡點,來實現處女座們希望看到的“完美“結果。
本篇的程式,可以在
https://github.com/kentliu2007/EFCoreDemo/tree/master/InheritanceWithEntitySplit 下載。建議大家可以下載之後對照著程式來閱讀本篇(我用的是VS2017)。
直接配置EFCore的DBContext可行否?
我們能否透過在DBContext裡面配置好Entity和資料表的關係,是否就可以?
看下麵的程式:
- DBContext:
- Unit Test:
實際上,出錯的話,Unit Test才可以透過。所以基於這樣的結果,我們知道,沒戲。
拉倒吧。哪怕我們已經很認真地配置好了Entity和資料表的關係。已經精確到每個欄位級別都沒有漏了。
結果其實程式會報錯的。不信?跑跑Unit Test就知道了。
用EFCore Lazy Loading來實現吧
有什麼辦法來實現?
還記不記得我的部落格裡面有一篇如何用EFCore Lazy Loading實現Entity Split?在這一篇裡面,我們用了 Lazy Loading的功能,用walk around的方式實現了 entity split。
這個walk around的思路,我們可以借鑒用起來:
- 對Students和Teachers資料表,我們可以建立兩個對應的類,分別弄個InternalStudent和InternalTeacher的類。
- DBContext裡面,設定好InternalStudent以及InternalTeacher的對映關係
- Student / Teacher 類特有的屬性,我們用Lazy Loading的方式,在getter/setter裡面,改為訪問上述InternalStudent / InternalTeacher實體所對應的屬性。
資料表和程式
- 資料表
表的索引和倆外來鍵,和上一篇差不多,就不騙篇幅了。
( 如果拿著這個資料表和一開始的邏輯設計比較,我們又會發現出現了偏差很小的β角彩蛋 ) - Solution
- 程式
- User
- InternalStudent
- Student
- InternalTeacher和Teacher的程式和InternalStudent以及Student差不多思路,就不騙篇幅了。
- DBContext
- Unit Test
- Demo資料
- User
搞定了。
就這樣,用walk around的做法,實現了“完美”的平衡點,讓處女座的DB First er程式猿不再糾結。還可以吧? 😛
結語
這種walk around的做法,雖然有點走火入魔,但是在 EFCore更好地支援類繼承,或者Entity Split之前,咱們先湊合著用起來吧。
相信隨著EFCore版本的不斷更新,”麵包會有的,牛奶會有的,一切都會有的。”。