1、EF簡介
ADO.NET Entity Framework 是微軟以 ADO.NET 為基礎所發展出來的對象關系對應 (O/R Mapping) 解決方案。
該框架曾經為.NET Framework的一部分,但version 6之后從.NET Framework分離出來。
EF是微軟開發的一款ORM框架。ORM框架能夠自動實現Entity實體的屬性與關系型數據庫字段的映射,增刪改查的sql腳本由ORM來
自動生成,使我們編碼時不用考慮數據庫數據結構,而是以操作實體對象的形式來完成與數據庫的交互。
與傳統開發方式相比ORM可以使我們編寫更少的代碼來創建和維護應用程序。
ef開發模式有多種:code first、database first。
本文只是介紹database first,想要了解其他一些開發模式,請自行網上查找資料。
2、database first
“Database First”模式顧名思義:“數據庫優先”,使用這種模式的前提是應用程序已經擁有相應的數據庫,
咱們可以使用EF設計工具由數據庫生成數據模型類。
3、操作准備
(1)、本示例的開發環境是vs2012\sqlservel 2012
當然選擇別的開發環境、數據庫同樣也是可以的。
(2)、創建數據庫、數據表
第一、打開sqlserver數據庫,新建一個數據庫(database)並命名為:SchoolDB
第二、創建數據表:T_Class
USE SchoolDB
GO
CREATE TABLE T_Class(
ID int primary key IDENTITY(1,1) NOT NULL,
Name nvarchar(max) NOT NULL
)
第三、創建數據表:T_Student
USE SchoolDB
GO
CREATE TABLE T_Student(
ID int primary key identity(1,1) NOT NULL,
Name nvarchar(max) NOT NULL,
ClassID int NOT NULL,
Phone nvarchar(max) NOT NULL,
Email nvarchar(max) NOT NULL,
FOREIGN KEY(ClassID) REFERENCES T_Class (ID)
)
第四、創建數據表:T_Teacher
USE [SchoolDB]
GO
CREATE TABLE T_Teacher(
ID int PRIMARY KEY IDENTITY(1,1) NOT NULL,
Name nvarchar(max) NOT NULL,
Address nvarchar(max) NOT NULL,
Phone nvarchar(max) NOT NULL,
Email nvarchar(max) NOT NULL,
ClassID int NOT NULL,
FOREIGN KEY(ClassID) REFERENCES T_Class(ID)
)
4、利用EF,根據database first 原則生成實體類的步驟
第一步、打開vs2012 ,新建一個控制台應用程序,並名為:EFDatabaseFirstTest
這里不再贅述,不會的網上查一下資料
第二步:創建實體模型
在第一步創建的項目名稱上右擊, 添加“新建項”→Ado.Net實體數據模型
命名為:Model1.edmx
如下圖所示:
第三步:與現有的數據庫進行連接生成EF實體
在做這步之前,首先確定你是否已經有現有數據庫
(1)、選擇從數據庫生成實體數據模型
(2)、新建連接到現有的數據庫,
(3)、點擊下一步,選擇我們要生成實體對應的表、試圖、存儲過程等,
(4)、最后點擊完成,則系統幫我們生成了數據庫實體類以及EDMX的定義文件。
生成的文件目錄如下圖所示:
到現在我們前期的准備工作就結束了,接下來我們將使用EF幫我們生成的數據庫網關來操作數據庫了
5、數據的增刪改查操作
(1)、插入數據

/// <summary> /// 向數據庫插入一條學生信息 /// </summary> public bool AddStudent() { //創建數據庫訪問網關 //SchoolDBEntities在配置文件中(App.config中) using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { //創建student一個實體 T_Student student = new T_Student() { ClassID = 1, Email = "405325966@qq.com", Name = "張三", Phone = "63339236", T_Class = new T_Class() { ID = 1, Name = "一班" } }; //將創建的實體,放入網關的數據實體的集合 schoolEntities.T_Student.Add(student); //寫回數據庫 int k1= schoolEntities.SaveChanges(); return k1 > 0; } }
(2)、編輯數據
方法一:每次都需要對所有字段進行修改,效率低
示例代碼:

/// <summary> /// eidt 編輯student信息 /// </summary> /// <returns></returns> public bool EditStudent01() { //說明,編輯的時候需要給主鍵賦值 //修改所有的字段 //編輯 //創建數據庫訪問網關 //SchoolDBEntities在配置文件中 using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { T_Student student = new T_Student { ID =1,//編輯ID=1的學生的信息 ClassID = 4, Email = "tengxun@126.com", Name = "李四", Phone = "139******" }; //將實體附加到對象管理器中 schoolEntities.T_Student.Attach(student); //把當前實體的狀態改為Modified schoolEntities.Entry(student).State = EntityState.Modified; int k1= schoolEntities.SaveChanges(); return k1 > 0; } }
方法二:編輯、修改部分字段(屬性)
示例代碼:只是編輯Phone、Email兩個字段

public bool EditStudent02() { //說明,編輯的時候需要給主鍵賦值 //修改所有的字段 //編輯 //創建數據庫訪問網關 //SchoolDBEntities在配置文件中 using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { T_Student student = new T_Student { ID =1,//編輯ID=1的學生的信息 ClassID = 4, Email = "360@126.com", Name = "李留", Phone = "158******" }; //將實體附加到對象管理器中 schoolEntities.T_Student.Attach(student); //獲取到user的狀態實體,可以修改其狀態 var setEntry = ((IObjectContextAdapter)schoolEntities).ObjectContext.ObjectStateManager.GetObjectStateEntry(student); //只修改實體的Name屬性和Age屬性 //修改需要對主鍵賦值,注意:這里需要對所有字段賦值,沒有賦值的字段會用NULL更新到數據庫,當然數據庫設計的時候字段允許為null才可以 setEntry.SetModifiedProperty("Email"); setEntry.SetModifiedProperty("Phone"); int k1= schoolEntities.SaveChanges(); return k1 > 0; } }
(3)、查詢:查詢通過LinQ查詢
//查詢到學生對應的班級的外鍵,注意是使用的linq to ef ,它是生成的命令樹,然后是生成的sql
var cls = (from c in schoolEntities.T_Class
where c.ID == 1
select c).SingleOrDefault<T_Class>();
注意:只有調用了FirstOrDefault, First, Single, ToList, ToArray等函數才會執行對數據庫的查詢
示例代碼:

//查詢獲得一個實體 public T_Class GetClass() { using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { T_Class classObj = (from c in schoolEntities.T_Class where c.ID == 2 select c).SingleOrDefault<T_Class>(); return classObj; } } /// <summary> /// 獲取實體列表 /// </summary> /// <returns></returns> public List<T_Class> GetClass02() { using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { var classObj = (from c in schoolEntities.T_Class select c).ToList<T_Class>(); return classObj; } }
(4)、刪除數據
//刪除,刪除只需要主鍵即可

/// <summary> /// 刪除有兩種方法,都在示例代碼中 /// </summary> /// <returns></returns> public bool deleteStudent() { //創建數據庫訪問網關 //SchoolDBEntities在配置文件中 using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { T_Student student = new T_Student() { ID = 1 }; //將實體附加到對象管理器中 schoolEntities.T_Student.Attach(student); //方法一: //schoolEntities.T_Teacher.Remove(teacher); //方法二:把當前實體的狀態改為刪除 schoolEntities.Entry(student).State = EntityState.Deleted; int k1=schoolEntities.SaveChanges();//不論是方法一還是方法二 這一句代碼都是必須的 return k1 > 0; } }
(5)、使用事務
EF對事務進行了封裝:context的saveChange()是有事務性的。
示例代碼:
說明:添加多條記錄的時候,最后可以只執行一次 schoolEntities.SaveChanges();
示例代碼:

/// <summary> /// 使用事務 /// </summary> /// <returns></returns> public bool UserTranAddStu() { //使用事務 //創建數據庫訪問網關 //SchoolDBEntities在配置文件中 using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { //創建student一個實體 T_Student student = new T_Student() { Email = "guo123@126.com", Name = "長城", Phone = "1201", ClassID=1 }; //創建student一個實體 T_Student student01 = new T_Student() { Email = "guo456@126.com", Name = "萬里", Phone = "1202", ClassID = 2 }; //將創建的實體,放入網關的數據實體的集合 schoolEntities.T_Student.Add(student); schoolEntities.T_Student.Add(student01); //寫回數據庫 int k1= schoolEntities.SaveChanges(); return k1 == 2; } }
上面的示例也可以寫成:

public bool UserTranAddStu02() { //使用事務 //創建數據庫訪問網關 //SchoolDBEntities在配置文件中 using (SchoolDBEntities schoolEntities = new SchoolDBEntities()) { List<T_Student> students = new List<T_Student>(); //創建student一個實體 T_Student student = new T_Student() { Email = "guo123@126.com", Name = "長城", Phone = "1201", ClassID = 1 }; students.Add(student); //創建student一個實體 T_Student student01 = new T_Student() { Email = "guo456@126.com", Name = "萬里", Phone = "1202", ClassID = 2 }; students.Add(student01); //將創建的實體,放入網關的數據實體的集合 students.ForEach(x => { schoolEntities.T_Student.Add(x); }); //寫回數據庫 int k1 = schoolEntities.SaveChanges(); return k1 == students.Count; } }
6、擴展
這里所說的擴展是指在現有的數據庫中,新增數據表
(1)、新建數據表

use SchoolDB go create table T_Course ( Id int primary key identity(1,1) not null, Name nvarchar(50) null )
處理辦法
(1)、添加T_Course.cs實體類
方法:右擊 解決方案中項目中的“Model1.edmx”文件 -->打開
在打開的Model1.edmx[關系圖1]的空白處 右擊 選擇“從數據庫更新模型”
選擇新增的數據表,生成模型即可
如下圖所示:
(2)、然后既可以按照上面所講的方法insert、edit、delete、select 操作了。

public bool AddCourse() { //創建數據庫訪問網關 //SchoolDBEntities在配置文件中 using(SchoolDBEntities context=new SchoolDBEntities()) { //定義一個實體、、 T_Course course = new T_Course() { Name="領跑英語"}; //添加到網關的實體數據集合 context.T_Course.Add(course); //保存數據 int k1 = context.SaveChanges(); return k1 > 0; } }