Entity Framework(EF)(一)之database first


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;
            }
        }
View Code

  (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;


          }
      }
View Code

方法二:編輯、修改部分字段(屬性)
示例代碼:只是編輯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;


          }
      }
View Code

(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;
       }

   }
View Code

(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;

       }
   }  
View Code


(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;

       }
   }
View Code

上面的示例也可以寫成:

 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;

       }
   }
View Code

6、擴展
這里所說的擴展是指在現有的數據庫中,新增數據表
(1)、新建數據表

use SchoolDB
go
create table T_Course
(
Id int primary key identity(1,1) not null,
Name nvarchar(50) null
)
View Code

處理辦法
(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;
   
   }
   }
View Code

 


免責聲明!

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



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