優(yōu)雅地使用EntityFramework綜述_第1頁
優(yōu)雅地使用EntityFramework綜述_第2頁
優(yōu)雅地使用EntityFramework綜述_第3頁
優(yōu)雅地使用EntityFramework綜述_第4頁
優(yōu)雅地使用EntityFramework綜述_第5頁
已閱讀5頁,還剩15頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、優(yōu)雅地使用Entity Framework余志剛目錄1.Entity Framework 介紹 41.1. ORM 的歷史 61.2. 開始使用 Entity Framework 62.創(chuàng)建實體模型 72.1.創(chuàng)建模型概述 72.2.使用 Model First 創(chuàng)建模型 723 使用Database First創(chuàng)建模型724 使用Code First創(chuàng)建模型 7241. 數(shù)據(jù)庫已存在情景下使用 Code First創(chuàng)建模型 7242. 數(shù)據(jù)庫不存在情景下使用 Code First創(chuàng)建模型 73. 配置實體模型 73.1. 概述73.2. 配置實體的屬性 73.2.1. 使用 Data Ann

2、otation 酉己置73.2.2. 使用 Flue nt API 配置73.3. 配置實體的關(guān)系 73.3.1. 使用 Data Annotation 酉己置73.3.2. 使用 Flue nt API 配置73.4. 配置復(fù)雜類型的模型 73.4.1. 如何使用復(fù)雜類型 (ComplexType)73.4.2. 將實體映射到多個表(實體拆分) 73.4.3. 將多個實體映射到一個表(表拆分) 74. 使用EF 管理 Database74.1. 配置 Database的位置74.1.1. 使用連接字符串配置 74.1.2. 使用配置文件配置 84.1.3. 使用連接字符串的名稱配置84.1.

3、4. 重用數(shù)據(jù)庫鏈接 84.1.5. 使用Connection Factory管理EF的數(shù)據(jù)庫鏈接 842 Database的初始化94.2.1. 設(shè)置 Database的初始化器 94.2.2. 手工控制Database的初始化94.2.3. 使用初始化器插入種子數(shù)據(jù) 94.3. 使用 DbContext 94.3.1. DbContext 簡介94.3.2. 自定義 DbContext94.3.3. DbContext 的生命周期94.3.4. DbContext對數(shù)據(jù)庫連接的管理94.3.5. DbContet 的生命周期105. 參考資料 191. Entity Framework 介

4、紹最近在學(xué)習(xí)研究微軟的EF,通過這時間的學(xué)習(xí)研究,感覺這個EF目前來說還不是很完善,半成品。不過,據(jù)說在 .Net4.0 中,微軟將推薦使用此框架,并會有所 改善。而且,現(xiàn)在基本上所有數(shù)據(jù)庫均提供了對 EF 的支持。因此,為以后做技術(shù) 準(zhǔn)備可以學(xué)習(xí)研究以下。在.Net Framework SP1微軟包含一個實體框架(Entity Framework),此框架可以 理解成微軟的一個 ORM 產(chǎn)品。用于支持開發(fā)人員通過對概念性應(yīng)用程序模型編程(而不是直接對關(guān)系存儲架構(gòu)編程,來創(chuàng)建數(shù)據(jù)訪問應(yīng)用程序。目標(biāo)是降低面向數(shù) 據(jù)的應(yīng)用程序所需的代碼量并減輕維護(hù)工作。 Entity Framework 應(yīng)用程序

5、有以下優(yōu) 點:八、應(yīng)用程序可以通過更加以應(yīng)用程序為中心的概念性模型(包括具有繼承性、復(fù) 雜成員和關(guān)系的類型,來工作。應(yīng)用程序不再對特定的數(shù)據(jù)引擎或存儲架構(gòu)具有硬編碼依賴性。 可以在不更改應(yīng)用程序代碼的情況下更改概念性模型與特定于存儲的架構(gòu)之間 的映射。開發(fā)人員可以使用可映射到各種存儲架構(gòu)(可能在不同的數(shù)據(jù)庫管理系統(tǒng)中實 現(xiàn),的一致的應(yīng)用程序?qū)ο竽P?。多個概念性模型可以映射到同一個存儲架構(gòu)。 語言集成查詢支持可為查詢提供針對概念性模型的編譯時語法驗證。實體框架 Entity Framework 是 ADO.NET 中的一組支持開發(fā)面向數(shù)據(jù)的軟件 應(yīng)用程序的技術(shù)。在EF中的實體數(shù)據(jù)模型(EDM,由

6、以下三種模型和具有相應(yīng)文 件擴(kuò)展名的映射文件進(jìn)行定義。概念架構(gòu)定義語言文件 (.csdl) - 定義概念模型。存儲架構(gòu)定義語言文件 (.ssdl) - 定義存儲模型(又稱邏輯模型, 。映射規(guī)范語言文件 (.msl) - 定義存儲模型與概念模型之間的映射。實體框架 使用這些基于 XML 的模型和映射文件將對概念模型中的實體和關(guān)系的 創(chuàng)建、讀取、更新和刪除操作轉(zhuǎn)換為數(shù)據(jù)源中的等效操作。 EDM 甚至支持將概念 模型中的實體映射到數(shù)據(jù)源中的存儲過程。 它提供以下方式用于查詢 EDM 并返回 對象:LINQ to Entities -提供語言集成查詢(LINQ)支持用于查詢在概念模型中定義 的實體類型

7、。Entity SQL -與存儲無關(guān)的SQL方言,直接使用概念模型中的實體并支持諸 如繼承和關(guān)系等EDM功能。查詢生成器方法-可以使用LINQ風(fēng)格的查詢方法構(gòu)造 Entity SQL查詢。FotllyLINQ CO Entities下圖演示用于訪問數(shù)據(jù)的實體框架體系結(jié)構(gòu):lEnumerableEDMEntitySQI,舍詢ErhtyClientI,Entity Da taReaderDBDatRedder b.Name.Contains(.NET).AsNoTracking().ToList();當(dāng)數(shù)據(jù)庫上下文從數(shù)據(jù)庫獲取數(shù)據(jù)行然后表示為實體的時候,默認(rèn)情況下,會保持 對內(nèi)存中實體對象是否與數(shù)

8、據(jù)庫中數(shù)據(jù)同步的追蹤。內(nèi)存中的數(shù)據(jù)作為緩存,當(dāng)你 更新實體的時候被用來更新。這個緩存在 Web 應(yīng)用程序中通常沒有必要,因為上 下文對象的實例生命期很短 ( 對于每一次請求創(chuàng)建一個新的,然后釋放 ) ,在實 體被再次使用之前數(shù)據(jù)庫上下文讀取的實體對象已經(jīng)被釋放了。你可以通過 AsNoTracking 方法來指定上下文對象是否追蹤實體對象。使用這個方 法常見的場景如下:對于查詢大量數(shù)據(jù)的查詢來說,關(guān)閉追蹤可以提高性能。 你更希望重新連接一個對象用來更新,盡管基于不同的目的以前獲取過同樣的 對象。由于數(shù)據(jù)庫上下文已經(jīng)追蹤了這個實體,你就不能連接你希望修改的實體。 防止出現(xiàn)這種情況的一種方式就是在原

9、來的查詢中使用 AsNoTracking 選項。Entity Framework Code First通過 DbContext.ChangeTracke對實體對象的變動進(jìn)行跟 蹤,實現(xiàn)跟蹤的方式有兩種:變動跟蹤快照和變動跟蹤代理。變動跟蹤快照:前面幾篇隨筆的示例都是通過實體對象變動快照跟蹤來實現(xiàn)數(shù) 據(jù)操作的,POCO模型不包含任何邏輯去通知 Entity Framework實體類屬性的變動。 Entity Framework 在第一次對象加載到內(nèi)存中時進(jìn)行一次快照,添加快照發(fā)生在返 回一次查詢或添加一個對象到 DbSet中時。當(dāng)Entity Framework需要知道對象的變 動時,將先把當(dāng)前

10、實體與快照中的對象進(jìn)行掃描對比。實現(xiàn)掃描對比的方法是調(diào)用 DbContext.ChangeTracker的 DetectChanges方法。變動跟蹤代理:變動跟蹤代理是一種會主動通知Entity Framework實體對象發(fā)生變動的機(jī)制。如:延遲加載的實現(xiàn)方式。要使用變動跟蹤代理,需要在定義的類 結(jié)構(gòu)中,Entity Framework可以在運行時從POCO類中創(chuàng)建動態(tài)類型并重寫 POCO 屬性。動態(tài)代理就是一種動態(tài)類型,包含重寫屬性和通知Entity Framework實體對象變動 的邏輯 。 Entity Framework 之 Code First 方 式中能夠自動調(diào)用 DbC on t

11、ext.Cha ngeTracker.DetectCha nge 的方法:? DbSet.Add? DbSet.FindDbSet.RemoveDbSet.AttachDbSet.Local? DbContext.SaveChanges? DbContext.GetValidationErrors? DbContext.Entry? DbChangeTracker.Entries? 任何在 DbSet 上進(jìn)行 LINQ 的查詢1、控制什么時間調(diào)用 DetectChanges大部分的實例對象的變動調(diào)整需要在Entity Framework進(jìn)行SaveChangeS時才會知道,但也可以根據(jù)需要調(diào)用

12、變動跟蹤獲取當(dāng)前對象的狀態(tài)。Entity Framework Code First 的 DbContext.DetectChanges在檢測實例對象的變動 時,大部分情況不會有性能的問題。 但當(dāng)有大量的實例對象在內(nèi)存中, 或 DbContext 有大量的操作時,自動的 DetectChanges 行為可能會一定程度的影響性能。 Entity Framework提供關(guān)閉自動的DetectChanges的功能,在需要的時候進(jìn)行手動調(diào)用。 using ( var ctx = newPortalContext()ctx.Configuration.AutoDetectChangesEnabled =

13、false ;var province = ctx.Provinces.Find( 1);province.ProvinceName = 測試;Console.WriteLine( Before DetectChanges:0 , ctx.Entry(province).State);ctx.ChangeTracker.DetectChanges();Console.WriteLine( After DetectChanges:0 , ctx.Entry(province).State);代碼運行結(jié)果:Before DetectChanges:Unchanged After DetectCha

14、nges:Modified2、獲取不帶變動跟蹤的實體查詢 在一些情況下,我們只需要查詢返回一個只讀的數(shù)據(jù)記錄,而不會對數(shù)據(jù) 記錄進(jìn)行任何的修改。這種時候不希望 Entity Framework 進(jìn)行不必要的狀態(tài)變動跟 蹤,可以使用 Entity Framework 的 AsNoTracking 方法來查詢返回不帶變動跟蹤的查 詢結(jié)果。5.3. 模型實體的代理對象為 POCO 實體類型創(chuàng)建實例時, 實體框架常常為充當(dāng)實體代理的動態(tài)生成的派 生類型創(chuàng)建實例。 此代理重寫實體的某些虛擬屬性, 這樣可在訪問屬性時插入掛鉤, 從而自動執(zhí)行操作。例如,此機(jī)制用于支持關(guān)系的延遲加載。當(dāng) EF 創(chuàng)建實體對象的

15、時候 ( 例如,在執(zhí)行查詢的時候 ) ,EF 經(jīng)常會創(chuàng)建動 態(tài)生成的派生自實體的代理對象。代理重寫了實體的虛擬屬性來插入在訪問屬性的 時候自動執(zhí)行的鉤子。例如,這種機(jī)制用來支持延遲加載或者關(guān)聯(lián)。多數(shù)時候你并不能察覺使用了代理,除了下面的情況之外: 有一些場景,你需要阻止 EF 創(chuàng)建代理實例。例如,序列化非代理的對象實例 可能比序列化代理對象實例更加有效。當(dāng)使用 new 操作符實例化實體的時候, 你并沒有得到代理實例。 這意味著你不 能獲得諸如延遲加載以及自動追蹤的能力。 一般沒有問題, 通常并不需要延遲加載, 因為你在創(chuàng)建數(shù)據(jù)庫中并不存在的實體。在將實體標(biāo)記為 Added 狀態(tài)的時候,也 不需

16、要追蹤。然而,如果你需要延遲加載,需要改變追蹤,就可以通過 DbSet 類的 Create 方法來創(chuàng)建實體代理對象。可能需要通過代理類型對象實例獲取真實實體類型??梢允褂?ObjectContext 類的 GetObjectType 方法來通過代理對象獲取實際對象。5.3.1. 禁用代理有時需要禁止實體框架創(chuàng)建代理實例。例如,人們通常認(rèn)為序列化非代理實例要比序列化代理實例容易得多。可通過清除 ProxyCreationEnabled 標(biāo)記來關(guān)閉代理 創(chuàng)建功能。上下文的構(gòu)造函數(shù)便是可執(zhí)行此操作的一個位置。例如:public class BloggingContext : DbContextpub

17、lic BloggingContext()this.Configuration.ProxyCreationEnabled = false;public DbSet Blogs get; set; public DbSet Posts get; set; 請注意,在無需代理執(zhí)行任何操作的情況下, EF 不會為類型創(chuàng)建代理。這意 味著,也可以通過使用封裝和 /或沒有虛擬屬性的類型,避免生成代理。有時需要禁 止實體框架創(chuàng)建代理實例。例如,人們通常認(rèn)為序列化非代理實例要比序列化代理 實例容易得多。可通過清除 ProxyCreationEnabled 標(biāo)記來關(guān)閉代理創(chuàng)建功能。上下 文的構(gòu)造函數(shù)便是可執(zhí)行

18、此操作的一個位置。例如:public class BloggingContext : DbContextpublic BloggingContext()this.Configuration.ProxyCreationEnabled = false;public DbSet Blogs get; set; public DbSet Posts get; set; 請注意,在無需代理執(zhí)行任何操作的情況下, EF 不會為類型創(chuàng)建代理。這意 味著,也可以通過使用封裝和 /或沒有虛擬屬性的類型,避免生成代理。5.3.2. 顯式創(chuàng)建代理實例通過使用 DbSet 的 Create 方法執(zhí)行此操作。例如:us

19、ing (var context = new BloggingContext()var blog = context.Blogs.Create();如果要創(chuàng)建派生實體類型的實例,可使用 Create 的通用版本。例如:using (var context = new BloggingContext()var admin = context.Users.Create();請注意, Create 方法不將已創(chuàng)建的實體添加或附加到上下文。 請注意,如果因為實體代理類型不執(zhí)行任何操作而導(dǎo)致創(chuàng)建的實體代理類型不包含 任何值, Create 方法將僅創(chuàng)建實體類型本身的實例。例如,如果實體類型已封裝和 /或

20、沒有虛擬屬性,則 Create 將僅創(chuàng)建實體類型的實例。5.3.3. 從代理類型獲取實際實體類型代理類型的名稱類似如下所示:System.Data.Entity.DynamicProxies .Blog_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E4 8E6可通過使用 ObjectContext 中的 GetObjectType 方法,查找此代理類型的實體類型。 例如:using (var context = new BloggingContext()var blog = context.Blogs.Find(1);v

21、ar entityType = ObjectContext.GetObjectType(blog.GetType();請注意,如果傳遞給 GetObjectType 的類型是非代理類型的實體類型的實例,則仍 將返回實體的類型。這意味著,始終可以使用此方法獲取實際的實體類型,而不用 再檢查類型是否是代理類型。5.3.4. 代理類加載的前提The Entity Framework creates proxies for POCO entities if the classes meet the requirements described below. POCO entities can have

22、 proxy objects that support change tracking or lazy loading. You can have lazy loading proxies without meeting the requirements for change tracking proxies, but if you meet the change tracking proxy requirements, then the lazy loading proxy will be created as well. You can disable lazy loading by se

23、tting the LazyLoadingEnabled option to false.簡單來說代理類是跟蹤和懶加載的前提。For either of these proxies to be created:代理類的前提A custom data class must be declared with public acces必.須是開放 (public) 申明A custom data class must not be sealed (NotInheritable in Visual Basic) 不能是 sealed申明A custom data class must not be a

24、bstract (MustI nherit in Visual Basic) 不 能是扌由象類A custom data class must have a public or protected constructor that does not have parameters. Use a protected constructor without parameters if you want the CreateObject method to be used to create a proxy for the POCO entity. Calling the CreateObject

25、method does not guaranteethe creation of the proxy: the POCO class must follow the other requireme nts that are described in this topic.必須有無參的構(gòu)造函數(shù)The class cannot implement the IEntityWithChangeTracker or IEntityWithRelationships interfaces because the proxy classes implement these interfaces. 不能繼承自

26、這兩個接口,因為代理類需要使用The ProxyCreatio nEn abled opti on must be set to true.ProxyCreati onEn able 必須開 啟For lazy load ing proxies:懶加載的前提Each navigation property must be declared as public, virtual (Overridable in Visual Basic), and not sealed (NotOverridable in Visual Basic) get accessor. The navigation pr

27、operty defined in the custom data class must have a corresponding navigation property in the con ceptual model. For more in formati on, see Loadi ng Related POCO En titie關(guān)聯(lián) 屬性必須由 virtual 標(biāo)簽,懶加載開啟For change tracking proxies:Each property that is mapped to a property of an entity type in the data model must have non-sealed (NotOverridable in Visual Basic), public, and virtual (Overridable in Visual Basic) get and set accesso關(guān)聯(lián)屬性必須有 virual標(biāo)簽且必須同時擁有 get,setA navigation property that represents the many end of a re

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論