靈動思緒EF(Entity FrameWork)


很久之前就想寫這篇文章了,但是由於種種原因,沒有將自己學習的EF知識整理成一片文章。今天我就用CodeFirst和ModelFirst兩種方式的簡單案例將自己學習的EF知識做個總結。

在講解EF之前,我們先來看下ORM

ORM全稱:(Object-Relation  Mapping)即對象-關系映射。ORM是將關系數據庫中的業務數據用對象的形式表現出來,並通過面向對象的方式將這些對象組織起來,實現系統業務邏輯的過程。

ORM簡介:

  ORM產生背景:

  1. 操作數據庫代碼的重復性

在ORM之前我們知道通過ADO.NET可以訪問數據庫。或者更進一步,學過三層架構的開發人員,知道可以將通過ADO.NET對數據庫的操作提取到一個單獨的類SqlHelper中,然后在DAL層調用SqlHelper類的方法實現對數據庫的操作。即使你這樣做了,在數據訪問層(DAL)層,還是要寫大量的代碼,而且我們都知道對數據庫的訪問無非增、刪、改、查四種操作,那么我們很容易想到我們做了大量的重復性工作。只是因為操作的表不同,我們可能需要花費大量的時間編寫針對該表的增刪改查語句,那么有沒有一種方式能自動生成這些語句呢?這樣的話,我們就可以吧主要的精力或者更多的時間投入到特殊業務的處理上。

2,大量SQL語句影響程序的擴展性和靈活性。

   我們知道之前我們編寫的程序和數據庫之間的耦合性很緊密,如果我們操作的是SQL Server數據庫,我們就需要引入對應的類庫(SqlConnection等),這樣如果需要更換數據庫,那么,數據訪問層的代碼就需要重新書寫。

ORM含義:

 

通過該圖,我們可以看出,O對應程序中的類Customer,就是對象,我們知道R含義為Relation,對應數據當中的關系表;M表示程序中對象和數據庫中關系表的映射關系。Mapping實際上是一個XML文件

接着我們再來看下面這張圖

通過該圖,我們可以看出業務實體,在數據庫中表現為關系數據,而在內存中表現為對象。應用程序處理對象很容易,但是很難處理關系數據。ORM做到了關系數據和對象數據之間的映射,ORM可以通過映射關系自動產生SQL語句,ORM在業務邏輯層和數據層之間充當橋梁。

ORM核心原則:

1,簡單性

2, 傳達性

3, 精確性

ORM優點:

1,  面向對象

不用編碼,就可以向操作對象一樣操作數據庫

2,  提高開發效率

ORM可以自動對實體對象與數據庫中表進行字段與屬性的映射,不需要單獨的數據訪問層就可以對數據進行增刪改查。

3,  方便轉移數據庫

當數據庫發生改變時,不需要對模型進行改動,只需要修改映射關系就可以 了。

ORM缺點:

1,  不夠靈活,對於復雜查詢,ORM力不從心。

2,  執行效率低於直接 編寫的SQL語句 。

3,  性能損耗,ORM中的映射和關系管理是以犧牲性能為代價的

4,   提高了學習成本。

ORM使用場合:

1,對性能要求不是很苛刻的程序

   有一個轉換的成本

2, 開發時間緊迫時

3, 有數據庫遷移需求時

常見ORM框架

ORM不是產品,是框架的總稱,面向對象的程序設計語言到關系數據庫的映射。

使程序員既可以利用面向對象語言的簡單易用性,又可以利用關系數據庫的技術優勢來實現應用程序的增刪改查操作。

1,              NHibernate:Hibernate在.NET平台下的版本

2,              iBatis.NET:iBatis在.NET平台的實現

3,              Linq to SQL(微軟不再更新):.NET針對SQL server的ORM框架

4,              ADO.NET  Entity  Framework:微軟在.NET4.0推出的領域驅動開發模型。

注意:ADO.NET  Entity  Framework是微軟以ADO.NET為基礎所發展出來的對象關系映射解決方案,只不過是對ADO.NET進行了一個更高層次的封裝。

.NET應用程序訪問數據庫的方式

1.手寫代碼通過ADO.NET類庫

2,DataSet結合DataAdapter結合

3,ORM

ORM解決方案:

    Linq to sql

   EF:數據庫的ER模型可以完全轉換成對象模型

EF體系結構

1, Data Providers:數據庫的相關操作

2, EDM:概念層和邏輯層的映射,應用程序構建在該層之上

3, 其他層:如何操作EDM

接下來,我們來看下EDM的概念

EDM(Entity  Data   Model):實體數據模型

能將我們對數據對象的操作為對數據庫的操作。

在EF中,我們對數據對象的操作,實際上是在操作EDM,

EDM會將對數據對象的操作發送到數據庫。

EDM三層:

CSDL(概念層)

定義對象模型,以面向對象的方式訪問數據,可以簡單理解為實體類

MSL(對應層)

負責上層的概念層結構與下層的存儲結構之間的映射

SSDL(存儲層)

負責與數據庫管理系統中的數據表做實體對應

EF圖解:

當我們通過應用程序對數據庫執行CRUD時,通過EF方式,實際上是對ObjectContext的操作,ObjectContext相當於EF的入口,ObjectContext拿到對應的消息(CRUD)后,通過ORM中的Mapping來將對象O映射成數據庫中的關系R。我們通過一個截圖來看下Mapping中存儲的內容。

 

然后我們就來通過CodeFirst的方式實現對數據庫的增刪改查操作。

CodeFirst方式

首先我們新建一個windows應用程序,然后對項目點擊右鍵,添加新建項,如下圖

然后點擊添加按鈕,

點擊下一步,

點擊新建連接

然后點擊確定按鈕,然后點擊下一步,

選中表節點,然后點擊完成即可。

然后打開項目中的edmx下的Designer.cs文件

打開上下文節點,

 ObjectContext前的類名就是我們所說的上下文。

那么下面我們開始編寫代碼:

        

  1  /*  注意點:數據庫中的表必須有主鍵,如果是模型先行,則模型也c必須有主鍵。
  2 
  3          */
  4 
  5         private void Form1_Load(object sender, EventArgs e)
  6 
  7         {
  8 
  9             // 實現EF第一種方式:CodeFirst:代碼先行機制
 10 
 11             /************************ 增加數據***********************/
 12 
 13             //01.創建EF上下文實例
 14 
 15             EFFirstEntities efFirst = new EFFirstEntities();
 16 
 17             #region 新增數據
 18 
 19             ////02.構造出一個實體
 20 
 21             //Student stu = new Student();
 22 
 23             //stu.Name = "張三";
 24 
 25             ////03.將實體對象添加到實體集合中
 26 
 27             //efFirst.Student.AddObject(stu);
 28 
 29             ////04.最后要告訴EM幫我去將數據保存到數據庫
 30 
 31             //efFirst.SaveChanges();
 32 
 33             #endregion
 34 
 35            /*************************修改數據************************/
 36 
 37            //02.構造出你要修改的實體
 38 
 39             #region 修改數據
 40 
 41             //Student stu = new Student();
 42 
 43             //stu.Name = "李四";
 44 
 45             //stu.ID = 4;
 46 
 47             ////03.將當前實體用EF進行跟蹤
 48 
 49             //efFirst.Student.Attach(stu);
 50 
 51             ////04.將狀態設置為Modified
 52 
 53             //efFirst.ObjectStateManager.ChangeObjectState(stu, EntityState.Modified);
 54 
 55             ////05.保存
 56 
 57             //efFirst.SaveChanges();
 58 
 59             #endregion
 60 
 61            
 62 
 63             /***********************刪除數據*************************/
 64 
 65             #region 刪除
 66 
 67             //Student stu = new Student();
 68 
 69             //stu.ID = 4;
 70 
 71             ////03.也是要跟蹤當前的實體對象
 72 
 73             //efFirst.Student.Attach(stu);
 74 
 75             //efFirst.ObjectStateManager.ChangeObjectState(stu, EntityState.Deleted);
 76 
 77             //efFirst.SaveChanges();
 78 
 79             #endregion
 80 
 81  
 82 
 83             /***************************查詢數據*************/
 84 
 85             //var 語法塘技術
 86 
 87             //foreach (var item in efFirst.Student)
 88 
 89             //{
 90 
 91             //    string result = string.Format("ID={0},Name={1}", item.ID, item.Name);
 92 
 93             //    MessageBox.Show(result);
 94 
 95             //}
 96 
 97             /****************** ***********通過linq方式查詢***********/
 98 
 99            //EF有延遲加載機制  select * from student where 1=1
100 
101             //所謂延遲加載機制,當你真正需要數據的時候,EF才幫我們加載
102 
103             var list = from c in efFirst.Student
104 
105                        where c.ID > 1
106 
107                        select c;
108 
109  
110 
111             foreach (var item in list)
112 
113             {
114 
115                 MessageBox.Show(item.Name);
116 
117             }

ModelFirst方式:

 方式類似,只是需要添加空模型,然后選擇數據源,過程不再贅述。

然后我們看下實現代碼。

 1  ModelFirstStudentContainer modelFirst = new ModelFirstStudentContainer();
 2             /*******************************添加************************************************/
 3             Customer customer = new Customer() { CName = "李小龍", CRemark = "功夫影星" };
 4             modelFirst.Customer.AddObject(customer);
 5             Order order1 = new Order() { OrderContent = "雙節棍", Customer = customer, OrderDate = DateTime.Now };
 6             modelFirst.Order.AddObject(order1);
 7 
 8             Order order2 = new Order() { OrderContent = "布棍", Customer = customer, OrderDate = DateTime.Now };
 9             modelFirst.Order.AddObject(order2);
10             modelFirst.SaveChanges();
11             /*************************************查詢*************************************/
12             var temp = from c in modelFirst.Customer
13                        where c.Order.Count >= 2
14                        select c;
15             foreach (var item in temp)
16             {
17                 foreach (var o in item.Order)
18                 {
19                     MessageBox.Show(o.OrderContent);
20                 }
21             }
22             /*********************************修改********************************************/
23             Customer cust = new Customer(){CID = 1,CName = "小李",CRemark = "英雄"};
24             modelFirst.Customer.Attach(cust);
25             modelFirst.ObjectStateManager.ChangeObjectState(cust, EntityState.Modified);
26             modelFirst.SaveChanges();
27             /*********************************刪除***********************************************/
28             var temp = from c in modelFirst.Order
29                        where c.Customer.CID == 1 
30                        select c;
31             foreach (var item in temp)
32             {
33                 modelFirst.Order.DeleteObject(item);
34             }
35             Customer cust = new Customer() 
36             {
37                 CID=1
38             };
39             
40             modelFirst.Customer.Attach(cust);
41             modelFirst.ObjectStateManager.ChangeObjectState(cust, EntityState.Deleted);
42             modelFirst.SaveChanges();

這次就講到這里,我們用兩種方式:代碼先行和模型方式通過EF對數據庫中數據進行了操作。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM