Entity Framework是ORMapping的一種具體實現,那ORMapping又是什麼呢?html
ORM--ObjectRelation Mapping,即對象關係映射框架/數據持久化框架,是根據實體對象操做數據表中數據的一種面向對象的操做框架。
sql
其實Entity Framework的底層也是調用Ado.Net,它是更高層次的封裝。做爲數據訪問的技術,EntityFramework的設計有高擴展性,這一點可體如今其映射定義的靈活性。數據庫
簡單地說,使用Entity Framework能夠充分地定義與數據表映射的實體,這個實體能夠直接用於業務邏輯層或做爲服務的數據契約。編程
使用EF後,能夠將實體類的設計工做徹底放在EDM的設計過程當中,而不須要手工寫那些大同小異的代碼,使人欣喜的是這個實體模型能夠在運行時修改並生效,作到一改全改。網絡
咱們開發時也不用再頻繁地與數據庫打交道,咱們操做實體模型的同時EF框架自動完成了對數據庫的操做。數據結構
對於一種新瞭解的技術,瞭解宏觀是必須的,可是要想盡快熟悉仍是要實踐一下的,咱們知道網絡上特別流行Codefist,下面就來講一說EF框架劃分的模式:架構
- DataBase First(數據庫優先)
- Model First(模型優先)
- CodeFirst(代碼優先)
固然,若是把Code First模式的兩種具體方式獨立出來,那就是四種了。app
一、DataBase First 傳統的表驅動方式建立EDM,而後經過EDM生成模型和數據層代碼。除生成實體模型和自跟蹤實現模型,還支持生成輕型DbContext。在設計器中逆向生成Model,並有Model自動生成全部的類。框架
二、Model First 先建立EDM模型,再生成DDL數據庫腳本和模型和數據層代碼。除生成實體模型和自跟蹤實現模型,支持生成輕型DbContext。在設計器中建立Model,並用Model生成數據庫,全部的類由Model自動生成。ide
三、Code First(New DataBase) :在代碼中定義類和映射關係並經過model生成數據庫,使用遷移技術更新數據庫。
四、Code First(Existing DataBase):在代碼中定義類和映射關係,給逆向工程提供工具。
雖然Code First靈活,可是需手動建立POCO模型,數據層DbContext及映射關係,經過Database.SetInitializer生成數據庫,這種方式較靈活,可是代碼工做較多。
2、EF三種編程方式的區別
- datebase first就是表明數據庫優先,那麼前提就是先建立數據庫和表。
- model first就是表明model優先,那麼前提也就是先建立model,而後根據model自動創建數據庫和表。
這兩EF的編程方式在使用的過程當中的區別爲:
一、添加新建項->添加ADO.NET實體數據模型的時候,database first選擇的是從數據庫生成。而Model first選擇的是空模型生成。
數據表的主鍵、外鍵,提早在DB設計中設置好。
而且在數據結構發生變化的時候,database first編程方式中是選擇從數據庫更新模型,model first選擇的是從模型生成數據庫。
modelFirst模式,若代碼已經生成好了,切換到另外一臺電腦上執行時,還沒有有數據庫。
則在sql文件中右鍵:執行,則會自動建立數據表【不過首先在db中手動建一個數據庫】。
注:只有第一次才能這樣操做,否則執行sql會將原表中的數據刪除掉(drop table),更新表結構時應該本身寫sql更新
- code first就不須要建立一個ADO.NET實體模型的過程,直接在model裏面寫實體類和dbcontext上下文類。
在Code-First中,默認生成的數據庫表的名稱爲類型的複數形式,如Model名爲「Player」,默認生成的數據庫表名爲「Players」。不少狀況下咱們並不想生成的數據庫表名爲複數形式,如何來控制呢?
在public class DBContext : DbContext重寫如下方法(去除複數的約束)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
3、EF三種編程方式實踐
一、Database FirstEntity Framework4.1以前EF支持「Database First」和「Model First」編程方式,從EF4.1開始EF開始支持支持「Code First」編程方式,今天簡單看一下EF三種編程方式。
開始介紹這三種EF操做方式以前,首先在Visual Studio 中創建一個數據庫鏈接,這裏咱們以「EFDemo」數據庫爲例:
你可使用EF設計工具根據數據庫生成數據數據類,你可使用Visual Studio模型設計器修改這些模型之間對應關係。
首先建立一個控制檯應用程序,而後右鍵添加新建項,選擇「ADO.NET Entity Data Model」,名稱輸入EFDemoDB:接着選擇從數據庫生成:下一步選擇數據庫鏈接,
建立完模型以後。你會發現Visual Studio自動爲你生成了「Class、「Student」兩個實體類和一個「EFDemoDB」數據庫上下文操做類:
二、Model First
此種方式,當須要增長表、更新表(增長字段)的時候
即更新模型(EF裏model生成步驟)
- 在edmx文件中 添加相應的表(實體)和字段(標量屬性),記得添加註釋【將顯示在代碼的Model註釋上,sql文件裏面不會有】,導航屬性不用手動添加。
注意,屬性中,實體集名稱(本身定義)纔是表的名字;
- 要添加表關係映射,在edmx空白處右鍵,選擇新建=》關聯,在彈出框裏選擇對應關係(多重性就是一對多什麼的,關聯是選擇與哪一個表進行關聯)【導航屬性會自動添加上】
注意:源是主表,目標是附表;
若 主鍵字段不是 用作兩表匹配的字段,則須要設置一對多,若主鍵字段是用作兩表匹配的字段,則能夠不設置爲一對多。
屬性-》引用約束中 設置兩個表相等的字段
- 在右建點擊edmx裡的模型,選擇從模型生成數據庫,即更新sql文件
- 右鍵Model1.Context.tt,而後點擊運行自定義工具; 或者手動 修改tt文件裏面的對應表的屬性
- 編譯生成OK
5.再執行相應的sql腳本【提早建好 或者採用生成的SQL文件裏的】,添加相應的表或字段
三、Code First
此種方式,不須要提早建立數據表,徹底從代碼開始。參考:Code First如何使用
4、EF加載方式
EF加載數據的方式,有預加載、延遲加載、顯式加載、按需加載。不一樣的加載方式都有不一樣的適用狀況,不能說哪一種方式好哪一種方式很差。但有一點是須要遵循的,那就是如何提升數據加載的效率。
一、延遲加載又叫惰性加載(Lazy Loading):即在須要或者使用的時候加載數據。默認狀況下,EF會使用延遲加載方式加載數據,即數據庫上下文的屬性:Configuration.LazyLoadingEnabled = true;
eg:var customers = from c in dbcontext.Customer select c;
二、預加載:若是你想讓全部數據一次性所有加載到內存中,那麼你須要使用.Include(Entity)方法 。.Include(Entity)方法容許級聯使用,你能夠預先加載具備多層級結構的數據。
eg:var q = from t in dbcontext.Customer.Include("Order") select t;
比較兩種加載方式
預加載:
• 減小數據訪問的延遲,在一次數據庫的訪問中返回全部的數據。不過缺點是,那就是若是數據量較大,一次性將全部數據載入內存每每並非最明智的選擇
• 減小與數據庫的交互次數
延遲加載:
• 很是寬容,由於只在須要的時候加載數據,不須要預先計劃
• 可能會由於數據訪問的延遲而下降性能,考慮到每訪問父實體的子實體時,就須要訪問數據庫。
三、顯式加載和延遲加載很是相似,不一樣的是顯式加載要手動關閉EF的延遲加載屬性,經過代碼ctx.Configuration.LazyLoadingEnabled = false;來完成。

dbcontext.Configuration.LazyLoadingEnabled = false; #region 顯式加載:查詢部分列數據,前提關閉 懶加載 //查詢表中部分列的數據 var items = from c in dbcontext.Customer select c; foreach (var item in items) { //條件判斷,只加載知足條件的數據,減小訪問數據庫的次數 if (item.Id < 5) { dbcontext.Entry(item).Collection(c => c.Order).Load(); Console.WriteLine(item.CusName); }
四、按需加載
其實EF並不存在按需加載的概念,可是這種方式很值得說一說,在加載數據的時候並非須要全部的屬性值,可能只須要一個Id,Name值。
因此咱們能夠對要查詢的實體進行一下篩選,只加載本身須要的某些列,避免加載大量的垃圾數據。在這裏按需加載的概念只是加載須要的列

#region 按需加載:查詢部分列數據 //查詢表中部分列的數據 var items = from c in dbcontext.Customer where c.Id < 10 select new { Id = c.Id, CName = c.CusName, OrderCount = c.Order.Count() }; foreach (var item in items) { Console.WriteLine(item.CName); } #endregion