Entity Framework是微軟以ADO.NET爲基礎所發展出來的對象關係映射(O/R Mapping)解決方案。該框架曾經爲.NET Framework的一部分,但Version 6以後從.NET Framework分離出來,可經過NuGet獲取。數據庫
Entity Framework利用抽象化數據結構的方式,將每一個數據庫對象都轉換成應用程序對象 (Entity),而數據字段都轉換爲屬性 (Property),關係則轉換爲結合屬性 (Association),讓數據庫的E/R(實體-聯繫圖)模型徹底的轉成對象模型,讓程序設計師能用最熟悉的編程語言來調用訪問。編程
對象-關係映射(Object Relational Mapping,簡稱ORM),用來把對象模型表示的對象映射到基於SQL的關係模型數據庫結構中去。這樣在具體的操做實體對象的時候,就不須要再去和複雜的SQL語句打交道,只需簡單的操做實體對象的屬性和方法。即用操做對象的方式來操做數據庫。服務器
其它ORM框架:Dapper、NHibernate等。數據結構
①、EF是創建在ADO.NET框架之上的,底層使用的是ADO.NET方法和類來執行數據操做,具體以下圖所示:app
②、EF支持SQL Server、MySQL、Oracle等主流數據庫。框架
③、EF採用約定大於配置的框架原則,能遵照約定就不要去配置。編程語言
④、EF開發數據庫的兩種形式先建數據庫或者先建模型。ide
⑤、EF三種開發模式:函數
◆ DataBase First (數據庫優先)學習
若是數據庫已存在,可使用VS自動生成數據模型以及相關的edmx文件。
使用簡單、方便,適用於數據庫會頻繁修改來知足新的需求。會出現修改了數據庫在程序中更新EF不起做用等問題。
◆ Model First (模型優先)
若是數據庫未建立,能夠在VS中利用Model設計數據庫,經過設計器生成映射信息(edmx文件),並生成數據庫。開發中不多使用。
◆ Code First (代碼優先)(*)
能夠經過設計的數據模型自動生成數據庫,也能夠經過已存在的數據庫生成數據模型,進行數據庫映射,都沒有edmx文件。
徹底控制代碼,即沒有自動生成的模型和上下文代碼。
數據庫由EF幫助生成,當修改模型後,EF使用DB Miguration自動幫助修改數據庫,但也能夠禁用Miguration,手動建立(推薦)。
上圖中前三種分別是DataBase First、Model First 和Code First,而第四種也是Code First。
那麼第三個和第四個到底有什麼區別?項目中如何使用?下面將會重點講解。(*)
⑥、EF三種開發模式使用比較,以下圖所示:
|
說明 |
使用 |
Database First (數據庫優先) |
數據庫已存在(生成edmx文件) |
數據庫頻繁改變 |
Model First (模型優先) |
數據庫未存在(生成edmx文件) |
開發中不多使用 |
Code First(代碼優先) |
數據庫存在/未存在(沒有生成edmx文件) |
徹底控制代碼 能夠禁用數據遷移 手動修改數據庫和實體類 |
①、建立一個應用程序選擇(.NET Framework類庫),選擇「添加」 ->「新建項」->點擊「數據」->選擇「ADO.NET 實體數據模型」,具體以下圖所示:
②、選擇模型內容來自「數據庫的EF設計器」,具體以下圖所示:
③、點擊新建鏈接如圖二所示,選擇數據庫地址、鏈接方式和數據庫,而後配置數據鏈接字符串如圖一所示,具體以下圖所示:
④、選擇要映射的「PersonInfo」表,具體以下圖所示:
⑤、建立完模型以後,你會發現Visual Studio自動生成了「Person」實體類和一個「EntityModelContext」數據庫上下文操做類,具體以下圖所示:
查詢數據,建立控制檯應用程序,經過NuGet包管理器,添加「Entity Framework」引用,而後配置相應的App.config的數據庫鏈接,建立測試代碼:
static void Main(string[] args) { //實例化數據庫上下文 using (var dbContext=new DemoDBEntities() ) { //使用Lambda表達式查詢數據 var info = dbContext.PersonInfo.Where(i => i.Name == "ZhangSan").ToList(); //使用Linq語句查詢 var info1 = from i in dbContext.PersonInfo where i.ID == 1 select i; //獲取查詢結果 foreach (var item in info) { Console.WriteLine(" Lambda方式的查詢結果:姓名:" + item.Name +" 年齡:"+item.Age); } //foreach (var item in info1) //{ // Console.WriteLine(" Linq 方式的查詢結果:姓名:" + item.Name + " 年齡:" + item.Age); //} Console.ReadLine(); } }
結果以下圖所示:
Database First是以數據庫爲中心的開發方式;
使用這種模式必需要先設計和建立數據庫,而後使用VS在已有數據庫的基礎上建立ADO.NET實體數據模型,而後使用EF訪問和操做數據庫;
若是數據庫表結構發生改變後,只需在模型設計視圖空白處右鍵,選擇「從數據庫更新模型」接着按照嚮導操做便可完成模型更新;
上面只是演示了一個查詢的小功能,EF的強大機制還需動手實踐和操做。
①、建立一個應用程序選擇(.NET Framework類庫),選擇「添加」 ->「新建項」->點擊「數據」->選擇「ADO.NET 實體數據模型」,具體以下圖所示:
②、選擇模型內容來自「空EF設計器模型」,具體以下圖所示:
③、開始設計實體,在空白處右擊,添加實體(UserInfo)和實體的屬性(eg:ID、Name、Age)等 ,具體以下圖所示:
④、實體模型設計完成,接下來要生成數據庫,選擇「根據模型生成數據庫」,具體以下圖所示:
⑤、建立數據庫,填寫相應的數據庫鏈接屬性,具體以下圖所示:
⑥、EF模型選擇和Visual Studio自動生成DDL文件,具體以下圖所示:
⑦、選擇自動建立的SQL腳本,此時數據已生成,執行腳本生成所須要的表,具體以下圖所示:
⑧、打開數據庫,能夠看到建立的數據庫以及表,具體以下圖所示:
查詢數據,建立控制檯應用程序,經過NuGet包管理器,添加「Entity Framework」引用,而後配置相應的App.config的數據庫鏈接,建立測試代碼:
static void Main(string[] args) { using (var dbContext = new ModelFirstContainer()) { //添加 UserInfo userModel = new UserInfo(); userModel.Name = "WangWu"; userModel.Age = 18; dbContext.UserInfo.Add(userModel); dbContext.SaveChanges(); //Linq查詢 var list = from i in dbContext.UserInfo where i.Name == "ZhangSan" select i; //Lambda 表達式查詢 var info = dbContext.UserInfo.Where(i => i.Name == "ZhangSan").ToList(); //獲取數據 foreach (var item in list) { Console.WriteLine(" Linq 方式的查詢結果:姓名:" + item.Name + " 年齡:" + item.Age); } foreach (var item in info) { Console.WriteLine(" Lambda方式的查詢結果:姓名:" + item.Name + " 年齡:" + item.Age); } Console.ReadLine(); } }
結果以下圖所示:
ModelFirst模式是實體模型先行的開發方式;
先設計實體,而後根據實體再去生成數據庫而且進行相應的操做;
使用這種方式的惟一緣由就是想體驗視覺實體設計器。
文章開始說到的Code First模式有兩種選擇一種是「空CodeFirst模型」,另外一種是「來自數據庫的CodeFirst」,具體以下圖所示:
上圖分別對兩種模式進行了描述,那它們到底該如何使用以及區別是什麼?請看下面的例子。
一、建立
①、建立一個應用程序選擇(.NET Framework類庫),選擇「添加」 ->「新建項」->點擊「數據」->選擇「ADO.NET 實體數據模型」,具體以下圖所示:
②、選擇模型內容來自「空Code First模型」,具體以下圖所示:
③、點擊完成,具體以下圖所示:
經過上圖咱們能夠看到生成相應的數據庫上下文以及數據庫鏈接字符串。(能夠根據本身的需求進行修改配置以及添加對應的實體)
二、應用
1)、鏈接配置文件(修改數據庫鏈接字符串,改爲咱們要存放數據庫服務器名)
<connectionStrings> <add name="CodeDB" connectionString="data source=.;initial catalog=CodeDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" /> </connectionStrings>
2)、代碼示例:
static void Main(string[] args) { using (var dbContext=new CodeDB() ) { UserInfo userModel = new UserInfo(); userModel.Name = "ZhangSan"; dbContext.UserInfo.Add(userModel); dbContext.SaveChanges(); Console.ReadKey(); } }
3)、運行上面代碼,「空Code First模型」,生成的數據庫以下圖所示:
從上圖能夠看出:
一、自動生成數據庫CodeDB;
二、數據庫中生成一張叫__MigrationHistory 的表(是用於記錄代碼遷移的歷史記錄,也是代碼遷移模式的開關,後面會聊);
三、數據庫中還建立一張實體類型(UserInfoes的表),包括字段名以及字段類型等信息;
四、利用代碼添加一條數據到UserInfoes的表中。
以上就是經過空Code First模式建立的數據庫以及表(經過代碼實現數據的建立以及表添加)上面的示例操做到這一步都顯示正常,可是咱們在實際開發中,
有時須要向數據庫中添加表以及修改表字段和屬性,那如今咱們在實體的代碼中添加一個Age字段,具體以下所示:
public class UserInfo { public int Id { get; set; } public string Name { get; set; } //實體中添加Age字段 public string Age { get; set; } }
如今運行程序
程序出現異常,那咱們來看看什麼意思「從數據庫建立以來支持CODEDB上下文的模型發生了變化,考慮使用代碼第一遷移來更新數據庫」,
說的就是模型與實際數據庫結構不一致,須要使用 Code First 中的數據遷移功能來解決問題,下面咱們就來看看數據遷移。
三、數據遷移的用法
一、什麼狀況須要進行數據遷移
在開發中使用空Code First模式,若是涉及到數據表的變動以及字段修改等操做,該如何作呢?固然若是是新項目,刪除數據庫,而後從新生成就好了,
那麼若是是線上的項目,數據庫中已經有數據了,那麼刪除數據庫從新生成就不行了,那麼該如何解決呢?EF Code First提供了一種數據遷移的操做。
二、如何進行數據遷移
● 手動遷移
當模型與實際數據庫結構不一致時,就須要使用數據遷移。數據遷移咱們須要掌握三個方法,它們分別是:
1) 在當前項目中啓用數據遷移 Enable-Migrations
2) 添加遷移版本 Add-Migration 版本名稱
3) 更新數據庫 Update-Database
第一步,選擇須要啓用數據遷移的項目,打開「視圖」->「其它窗口」->「程序包管理器控制檯」 或者能夠按快捷鍵 Alt+V,E,O,
而後輸入命令:Enable-Migrations,具體以下圖所示:
顯示當前項目中已啓用數據遷移,項目中會多出 Migrations文件夾以及相關代碼(Migrations文件夾主要是數據遷移的信息),具體以下圖所示
第二步因爲咱們的模型已經發生了改變,因此須要添加一個新的遷移版本,在程序包管理控制檯
執行以下命令:Add-Migration v1.0 ( 其中的v1.0表示版本號,名稱能夠自定義),此時再看項目中就會多出一個文件:
第三步經過數據遷移代碼能夠看到數據庫是如何進行更新和修改,想要讓數據庫發生改變,爲表添加一個Age字段,
仍是須要用到第三個命令:Update-Database(執行成功以後,表中就會添加一個 Age字段)
完成以上三個步驟,此時的模型與實際數據庫結構已經一致,再運行程序,程序就不會報錯了。
● 自動遷移
上面咱們利用命令方式手動完成數據遷移的,那麼若是咱們在實際開發中,每次修改完模型都要這樣更新數據庫嗎?若是表中有數據時,是否會丟失數據?
固然還有一種方式自動遷移,咱們須要在項目中啓用Migrations,而後在Configuration類中設置AutomaticMigrationsEnabled設置爲true
還須要在DbContext構造函數中寫上這句
Database.SetInitializer(new MigrateDatabaseToLatestVersion<EntityContext, Configuration>("DBConnectionString")),
經過構造函數把數據庫更新爲最新,具體以下圖所示:
說明:若是不喜歡自動遷移,能夠手工完成這個操做。手工遷移的好處後,能夠隨時退回到某個指定的遷移版本。遷移文件也能夠進行版本管理有利於團隊開發。
經過使用Code First模式建立出來的數據庫,默認是開啓了數據遷移,若是咱們模型進行了修改,那麼就須要在項目中開啓數據遷移,進行模型和數據庫同步。
數據遷移有分爲手動遷移和自動遷移,上面已講解,能夠根據本身的項目需求進行選擇。
可是在實際開發中進行數據遷移不免會出現一些問題,若是數據庫存有大量數據,遷移過程有可能致使數據丟失,每次更新模型都要進行數據遷移,
給咱們開發帶來不少不便,可是仍是想用代碼先行模式開發,那麼我就可使用「來自數據庫的Code First」的方式,默認是關閉數據遷移的,
方便咱們隨時修改數據庫以及模型,提升開發效率,推薦使用,請看下面講解。
◆ 數據庫已存在而且不想啓用數據庫遷移;
◆ 習慣經過手動修改實體類,手動修改數據庫表結構,來同步數據庫和模型;
◆ 實現代用優先原則。
①、建立一個應用程序選擇(.NET Framework類庫),選擇「添加」 ->「新建項」->點擊「數據」->選擇「ADO.NET 實體數據模型」,具體以下圖所示:
②、選擇模型內容來自「來自數據庫的Code First」,具體以下圖所示:
③、選擇鏈接建據庫,填寫相應的數據庫鏈接屬性,具體以下圖所示:
④、選擇須要的數據庫對象,具體以下圖所示:
⑤、點擊完成,項目中生成相應的數據庫上下文,具體以下圖所示:
static void Main(string[] args) { using (var dbContext=new CodeEntity() ) { PersonInfo userModel = new PersonInfo(); userModel.Name = "LiSi"; dbContext.PersonInfo.Add(userModel); dbContext.SaveChanges(); Console.ReadKey(); } }
經過上面的示例代碼運行咱們能夠看到,「來自數據庫的Code First」,咱們能夠經過手動建立數據庫,手動修改實體,方便咱們隨時修改數據庫和實體,
並且還不會生成__MigrationHistory 的表,也不用進行數據遷移,這種方式能夠更好地提現Code First的好處。
1)Code First模式中,當模型與表結構不一致時,程序會報錯,有兩種方式使模型和表結構一致,一種是手動修改模型代碼和表結構,另外一種是使用數據遷移功能。
這兩種方式不是想選哪個就選哪個,取決因而否使用了數據遷移 。
2)使用空Code First模型建立的數據庫默認是開啓數據遷移的;
3)使用來自數據庫的Code First模式中的數據庫,默認是關閉數據遷移的。
4)使用來自數據庫的Code First模式,經過手動改寫實體類,手動改數據庫表結構,來同步模型與實際表結構,能夠徹底本身控制代碼,推薦使用。
Database First:用於數據庫已經存在,可使用VS自動生成數據模型,已經相關的edmx信息。
Model First:數據庫未建立,能夠在VS中利用Model設計數據庫,經過設計器生成映射信息(edmx文件),並自動生成數據庫。
Code First:經過設計的數據模型自動生成數據庫,不須要額外edmx文件,也可經過已存在的數據庫生成數據模型,進行數據庫映射,一樣不須要edmx文件。
優秀是一種習慣,歡迎你們關注學習