新聞中心
繼承在各種編程中應(yīng)用很多,但是ADO.NET Entity Framework繼承還存在一定程度的不足,很可能出現(xiàn)映射錯誤,必須手工來維護(hù)EDMX中的MSL部分。

站在用戶的角度思考問題,與客戶深入溝通,找到昆都侖網(wǎng)站設(shè)計與昆都侖網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請域名、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋昆都侖地區(qū)。
ADO.NET Entity Framework繼承(以下簡稱ADO.NET EF)有一個非??尚诺倪\行時。之所以不敢在項目中廣泛使用是因為其糟糕的設(shè)計時。這個DSL設(shè)計時糟糕在哪里呢?其一,只能是先設(shè)計好數(shù)據(jù)庫后設(shè)計實體模型;其二,如果你修改了數(shù)據(jù)庫結(jié)構(gòu),再更新實體模型時,你所做的修改全部作廢,最糟糕的是,很可能會出現(xiàn)映射錯誤,你必須手工來維護(hù)EDMX中的MSL部分。通常數(shù)據(jù)庫結(jié)構(gòu)的修改會成為你的噩夢。
還必須指出一點,ADO.NET Entity Framework繼承在MSDN中的文檔是有問題的。不信你看我的發(fā)現(xiàn):MSDN,微軟怎么會這樣啊?
不得不承認(rèn),ADO.NET Entity Framework繼承的運行時對繼承關(guān)系的處理是非常讓人舒服的。本文帶你去體驗一下ADO.NET EF的繼承。
與通常的繼承關(guān)系映射一樣,支持三種方式:
◆一體系一表方式
◆一類一表方式
◆一具體類一表方式
對于***種方式和第三種方式,我是非常不屑的。我有文章講過我的看法:細(xì)說繼承關(guān)系映射。
***種方式有一篇文章已經(jīng)講了具體的操作方式:Single Table Inheritance in Entity Framework。這種方式有什么問題呢?那個“Type”字段我們是可以接受的,因為在運行時這個字段完全是透明的;但是那個“Salary”、“Rate”和“Hours”可以為空,這個我們不能接受,因為這意味著例如我們存貯一個SalariedExployee實體,可以堂而皇之地不給Salary賦值,而導(dǎo)致業(yè)務(wù)錯誤。這便是我所反感的“可空冗余”。不過凡事都有例外,如果派生類中的屬性剛好都是可空的,那這個可空就不冗余了,而單表繼承簡單高效的好處就可以坐收了。
第三種方式我是無法接受的,因為根本解決不了我多次提到的“關(guān)系共享”的問題。
還好,ADO.NET EF提供了***的第二種方式支持。有文章講這個方式:
Entity Framework Modeling : Entity Splitting
Entity Framework Modeling: Entity Splitting Part II
不過,我沒有按這篇文章所提示的方式設(shè)置成功,也許我的環(huán)境不同。重要的是,我明白了設(shè)置繼承的幾個要點:***,不要手工修改BaseType來設(shè)置繼承,而是要用上下文菜單中的“添加”→“繼承”的方式。我們于是相信,除了BaseType以外,ADO.NET EF的DSL為EDMX中的MSL部分加入了某些內(nèi)容。第二,手工刪除派生類中的關(guān)鍵字段屬性。第三,注意操作順序。
現(xiàn)在用一個實例來說明。這個例子用于解決關(guān)于權(quán)限的問題。業(yè)務(wù)系統(tǒng)對權(quán)限的判斷僅根據(jù)其是否擁有某個“權(quán)柄”。這個權(quán)柄用一個字符串表示在Privilege表中。這個權(quán)柄只可以授予給角色。用戶和用戶組都可以隸屬于某個角色,用戶組中的用戶可以從該用戶組繼承所有的角色。實際上的應(yīng)用可能會在權(quán)柄上再做一些文章,例如加上權(quán)柄作用域?qū)ο?。這與本主題沒有關(guān)系,就此省略。
下圖是數(shù)據(jù)庫的設(shè)計:
在Visual Studio 2008中建立一個類庫項目。新增一個名叫“InheritanceDemoModel.edmx”的實體數(shù)據(jù)模型,并從建立好的數(shù)據(jù)庫生成,把實體連接設(shè)置命名為“DemoEntities”。于是,得到這個最初的成果:
先刪除UserOrGroup和User之間的關(guān)系,再刪除UserOrGroup與Group之間的關(guān)系,然后把所有的實體集名稱改成復(fù)數(shù)。
現(xiàn)在加入兩個繼承關(guān)系:一個是UserOrGroup為基,Group為派生;另一個是UserOrGroup為基,User為派生。然后,變成這樣:
下一步,先把UserOrGroup的“抽象”屬性改為“true”,再刪除User的UserId屬性和Group的GroupId屬性。刪除這兩個屬性以后,要分別把原來的兩個字段(Column)映射到UserOrGroup的Id字段:
***一步,由于刪除了User的UserId屬性和Group的GroupId屬性,Group的Users屬性和User的Groups屬性映射被破壞了,需要重新映射:
保存,完成映射。接下來可以做幾個測試,例如,測試分別創(chuàng)建幾個Privilege、Role、Group、User,然后用一個簡單的Linq表達(dá)式來獲取某個User所有的權(quán)柄。
代碼就不貼了,有興趣下載代碼吧。
ADO.NET Entity Framework繼承的三種形式就介紹到這里。
【編輯推薦】
- 什么是ADO.NET:數(shù)據(jù)源的連接樞紐
- 淺談如何更好的打開和關(guān)閉ADO.NET連接池
- ADO.NET中SQL Server數(shù)據(jù)庫連接池
- ADO.NET中的多數(shù)據(jù)表操作讀取
- 淺談ADO.NET中的五個主要對象
文章名稱:ADO.NET Entity Framework繼承的三種形式
文章鏈接:http://fisionsoft.com.cn/article/dphspie.html


咨詢
建站咨詢
