EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射
為什么80%的碼農都做不了架構師?>>> ??
EF里的默認映射以及如何使用Data Annotations和Fluent API配置數據庫的映射
I.EF里的默認映射
上篇文章演示的通過定義實體類就可以自動生成數據庫,并且EF自動設置了數據庫的主鍵、外鍵以及表名和字段的類型等,這就是EF里的默認映射。具體分為:
摘自這里
默認的映射一般只是簡單映射,方便使用罷了。當然這些都是可以進行修改的,請往下看。
II.使用Data Annotations和Fluent API配置數據庫的映射
Data Annotations翻譯過來就是數據注解,是通過直接在實體類的屬性上加注類似標簽的東西達到對數據庫的映射;
Fluent API翻譯過來就是流利的API,Fluent API是在DbContext中定義數據庫配置的一種方式。要使用Fluent API 就必須在你自定義的繼承自DbContext的類中重載OnModelCreating這個方法。注意:
實戰:
1.Data Annotations:
設置Destination表的Name不為null:
很簡單,直接在屬性上加[Required]標注即可;
2.Fluent API:
用Fluent api必須重寫OnModelCreating方法,我們在上下文類里重寫下OnModelCreating方法并添加不為空的配置:
方法分析:先找到需要配置的實體類,然后點Property就是點出屬性,=>是lambda表達式的寫法,找到Name屬性,然后調用IsRequired方法設置不為null。初見這東西肯定不好理解,多寫寫就熟悉了。
兩種配置方式個人更喜歡Fluent API的方式,故放出的demo中Data Annotations也是有的,不過都被注釋了。隨著開發的深入,有些東西還是必須用Fluent API的方式才能配置出來的。
注意:我的類庫都修改了默認命名空間(右鍵類庫 - 屬性),都加了個CodeFirst. 方便區分,其他類庫中調用,我也是習慣用完整的命名空間.類庫再.實體類來調用。
思考:使用Fluent API方式配置,每次都需要在OnModelCreating方法里寫上一行配置,這樣一個實體類如果有3個屬性需要配置,10個實體類就需要配置30個,那么就得在OnModelCreating方法里寫30行,很麻煩且不易維護。
解決辦法:注意返回值可以看出modelBuilder的Entity<>泛型方法的返回值是EntityTypeConfiguration<>泛型類。我們可以定義一個繼承自EntityTypeConfiguration<>泛型類的類來定義domain中每個類的數據庫配置。
ok,我們在DataAccess類庫下新建一個繼承自EntityTypeConfiguration<>泛型類的DestinationMap類,在構造函數里寫上配置:
需添加引用:using System.Data.Entity.ModelConfiguration;
這樣,以后Destination需要配置的都來這里配置,然后添加到上下文中的OnModelCreating方法即可:
其他類的配置也是這樣,先添加一個類名+Map的方法(命名隨意),然后添加到OnModelCreating方法。
隨意配置一些屬性,然后跑下程序看生成的數據庫:
可見:Name列已經不可空,Description也設置了長度不超過500等等。
注意:如果重新跑程序生成數據庫報這個錯:
The model backing the 'BreakAwayContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
意思就是,當前數據庫正在使用中,無法刪除再重新生成。這個時候斷開數據庫連接,再跑下程序就可以了。以后每次配置實體類再重新跑程序都需要斷開數據庫連接。
不知道大家還記不記得第一篇文章講的EdmMetadata這個表,EF會自動生成這個表。這個表是監控實體類變化的,其實是個詬病,每次操作數據庫都會發訪問這張表的sql到數據庫,用sql Profiler跟蹤下即可發現如下sql:
2013.08.07補充:感謝園長dudu在回復中(4樓)的糾正,不是每次操作數據庫都會發送sql到數據庫,只是在EF初始化的時候會發送訪問EdmMetadata表的sql到數據庫。另推薦dudu的兩篇文章供大家閱讀:讓Entity Framework不再私闖sys.databases 揭開Entity Framework LINQ查詢的一點面紗
SELECT TOP (1) [Extent1].[Id] AS [Id], [Extent1].[ModelHash] AS [ModelHash] FROM [dbo].[EdmMetadata] AS [Extent1] ORDER BY [Extent1].[Id] DESC注:sql Profiler是一個監控發送到數據庫sql語句的工具。sql server 2008自帶,操作簡單,如果不會請自行搜索相關資料。如果沒有這個工具,那么是數據庫版本不對或者數據庫裝出了問題。sql Profiler這工具后面講一對一、一對多、多對多的各種操作時會經常使用到,也是我們調試EF語句性能的好幫手:
擴展:可以在OnModelCreating方法里添加:
需引入命名空間:
using System.Data.Entity.ModelConfiguration.Conventions; using System.Data.Entity.Infrastructure;第一句是移除復數表名的契約,就是EF默認生成的表名都是實體類的復數形式,有這句,表名就是實體類的名字了,不會再加個s了,當然你也可以通過強大的Fluent API配置這個。
第二句就是移除對EdmMetadata表的訪問的,下次再操作數據庫,就不會有訪問EdmMetadata表的sql了。
注意:如果之前已經有數據庫了,那么再加上移除對EdmMetadata表訪問的配置再跑程序會報一個NotSupportedException的錯:
Model compatibility cannot be checked because the EdmMetadata type was not included in the model. Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions.
這個時候,先把BreakAwayConfigFile數據庫分離,然后在本地刪除掉數據庫文件,再跑程序就可以了。如果不知道sql server的mdf和ldf文件的默認路徑,請自行搜索。
結果跑了下程序,的確沒有產生對EdmMetadata表訪問的sql了,但是sql Profiler監控到了更多的sql語句被發送到了數據庫。當初為了少一個訪問EdmMetadata表的sql,結果多了更多的sql,并且如果再次生成數據庫還必須要手動分離現有數據庫并刪除硬盤上的數據庫文件。這里使不使用還是有待商量的,暫時注釋掉:
思考:EF小組設計EdmMetadata表肯定有它的道理,移除對其的訪問也不一定是科學的。這里僅做學習演示,真正的項目中可能也很少用Code First的方式生成數據庫的。至少4.1版本下的EF使用Code First是有缺陷的,每次都要干掉所有數據,這個肯定不合適。后續版本的EF有數據遷徙的功能能解決這個,目前只是學習4.1這個經典的EF版本。
補充:實際開發中還是database First的方式比較主流。
上面只演示了簡單的Data Annotations和Fluent API的一些簡單配置,其實還有很多,下面列出部分常用,初學者應該都試著敲敲,然后對照著生成的數據庫好好學習下如何配置:
部分摘自這里
目前階段看這個的確稍顯復雜,僅做了解和方便后期查閱。后續講一對一、一對多和多對多的關系時反復的手寫Fluent API的時候就會很好理解了。
源碼:點擊下載
EF Code First 系列文章導航:分類: 4.Entity Framework
轉載于:https://my.oschina.net/wzzz/blog/494743
總結
以上是生活随笔為你收集整理的EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hitpoint:外贸企业如何选择合适的
- 下一篇: mysql 获取当前日期及格式化