1. 程式人生 > >C# ORM—Entity Framework 之Code first(程式碼優先)(二)

C# ORM—Entity Framework 之Code first(程式碼優先)(二)

一、Entity Framework Code first(程式碼優先)使用過程

 

1.1Entity Framework 程式碼優先簡介

 

不得不提Entity Framework Code First這個介於牛A與牛C之間的功能,從4.1 開始的Code first使程式設計師,使軟體開發流程進入一個更加方便快捷的時代。

 

Code First是EntityFramework實現ORM的一種有利手段,因為傳統程式設計方式都是先建立資料庫,然後根據資料庫模型為應用程式建模,再進行開發;CodeFirst程式碼優先,先在程式中建立要對映到資料庫的實體結構,然後EntityFramework可以根據實體結構生成所對應的資料庫。

 

1.2 最新版本簡介(Entity Framework 5,現在VS2012中已出現EF6.0.0beta1版本了)

 

1.2.1 列舉支援是EF 久等的功能,並讓您在您的域類中擁有列舉屬性。EF5 讓列舉支援在 EF 設計器和Code First中是可用的。 1.2.2 現在,現有資料庫中的表值函式可以包含在使用 EF 設計器所建立的模型中。 1.2.3 可以使用DbGeography 和 DbGeometry 型別在模型中公開空間資料型別。空間資料可以包含在由EF 設計器或Code First所建立的模型中。 1.2.4 EF5 還包括一些重大的效能改進,Entity Framework 5相比EF4在效能上會有67%的提升 。使用這個版本EF的應用程式之所以效能提升,要部分歸功於LINQ to Entities查詢的自動編譯。自動編譯功能一直都是EF框架中的一部分,只是需要開發人員呼叫CompiledQuery.Compile才能夠使用。現在,EF 5會自動處理這步工作:當某個查詢首次執行時,它會被編譯並快取,從而使得後續請求可以避免重新完全編譯。EF 4為ESQL(嵌入式SQL)查詢使用了編譯後的查詢快取,而EF 5將該功能擴充套件到了LINQ to Entity查詢中。一旦緩衝中超過800個編譯後的查詢,某個回收演算法將開始生效並以每分鐘一次的週期清理快取。 實體依據LFRU(最近最早使用)原理從快取中移除。

 

1.3 Visual Studio 2012中的EF設計器,它也有一些新的功能:

 

1.3.1 現在模型可以被分為多個關係圖,在使用大型的模型時,這是很不錯的。您還可以應用著色到實體中來幫助您識別您的模型的分割槽。 1.3.2 改進了轉置模型的嚮導,使其更容易和更快地為查詢資料批量匯入儲存過程。

   

二、 Code First New Database使用

 

2.1 建立控制檯專案

 

2.2 新增引用最新的Entity Framework

 

專案上右鍵單擊—》管理NeGut程式包—》聯機,找到EntityFramework—》安裝 安裝之後即可看到packages.config

 

2.3 建立實體類

       
 1     public class Blog 2     { 3         public int BlogId { get; set; } 4         public string Name { get; set; } 5  6         public virtual List<Post> Posts { get; set; } 7     } 8     public class Post 9     {10         public int PostId { set; get; }11         public string Title { get; set; }12         public string Content { get; set; }13 14         public int BlogId { set; get; }15         public virtual Blog Blog { get; set; }16     }
      View Code  

2.4 建立資料上下文類

 

新增引用:using System.Data.Entity;並繼承DbContext

 

程式碼示例:

       
1     public class BlogContext : DbContext2     {3         public DbSet<Blog> Blogs { set; get; }4         public DbSet<Post> Posts { get; set; }5     }
      View Code  

2.5 編寫測試程式碼

       
 1             using (var db = new BlogContext()) 2             { 3                 Console.WriteLine("輸入一個新的Blog名稱"); 4                 var name = Console.ReadLine(); 5  6                 var blog = new Blog { Name = name }; 7                 db.Blogs.Add(blog); 8                 db.SaveChanges(); 9 10                 var query = from b in db.Blogs11                             orderby b.Name12                             select b;13 14                 foreach (var item in query)15                 {16                     Console.WriteLine(item.Name);17                 }18             }19             Console.ReadKey();
      View Code  

以上便是最基本的應用

 

2.6 檢視資料庫

 

開啟SQL Server物件資源管理器,一般資料庫會建立在本機的開啟資料庫預設例項物件上

 

2.7 使用擴充套件

 

使用“程式包管理器控制檯”檢視、操作生成資料庫模型:開啟方式:工具—》庫程式包管理器—》程式包管理器控制檯(注意要選擇成您要操作的專案)

 

主要是資料庫遷移(增加實體類(資料表)、增加實體類欄位(資料庫欄位))

 

具體使用(開啟“程式包管理器控制檯”):

 

1. 輸入命令:Enable-Migrations 啟用Code first Migration;執行成功後會產生Migrations資料夾及兩個類:Configuration.cs  和<timestamp>_InitialCreate.cs,這是一個用時間戳作為字首的類。如201307080301469_InitialCreate.cs 注:如果不小心刪除了201307080301469_InitialCreate.cs這個檔案,可以使用Enable-Migration -Force重新建立

 

1.1 新增欄位:如在Blog內增加Url

       
1     public class Blog2     {3         public int BlogId { get; set; }4         public string Name { get; set; }5         public string Url { get; set; }6 7         public virtual List<Post> Posts { get; set; }8     }
      View Code  

輸入命令:Add-Migration AddUrl,同時在Migrations下會有201307080524348_AddUrl.cs檔案 繼續輸入命令:Update-Database,更新資料庫

 

1.2 新增新的實體類檔案User

    
1     public class User2     {3         public string UserName { get; set; }4         public string DisplayName { get; set; }5     }
   

輸入命令:Add-Migration AddUser;(注可能提示沒有主鍵,此時要為表User建立主鍵,先新增引用:using System.ComponentModel.DataAnnotations;)

    
1     public class User2     {3         [Key]4         public string UserName { get; set; }5         public string DisplayName { get; set; }6     }
   

再次執行:Add-Migration AddUser;在執行Update-Database,檢視資料庫管理工具資料庫已建立

 

1.3 修改欄位

 

修改User實體類中的DisplayName為“display_name”在資料上下文類BlogContext中新增以下程式碼:

    
1     protected override void OnModelCreating(DbModelBuilder modelBuilder)2         {3             modelBuilder.Entity<User>()4                 .Property(u => u.DisplayName)5                 .HasColumnName("display_name");6         }
   

輸入命令:Add-Migration ChangeDisplayName  ,在執行Update-Database,即可

 

1.4 刪除某一個欄位:刪除Blog實體類中的Url

 

首先在實體類中刪除此欄位

    
1     public class Blog2     {3         public int BlogId { get; set; }4         public string Name { get; set; }5 6         public virtual List<Post> Posts { get; set; }7     }
   

以上程式碼已刪除。 輸入命令:Add-Migration DeleteUrl ,之後在執行Update-Database即可。。

 

三、Code First An Existing Database使用(資料遷移功能暫時不能使用)

 

3.1 下載安裝擴充套件外掛

 

工具—》擴充套件和更新—》聯機,查詢“Entity Framework Power Tools”,進行下載,安裝,重新啟動。檢視是否安裝成功,工具—》擴充套件和更新—》已安裝,是否有此工具

 

3.2 新建資料表Blogs

       
1 CREATE TABLE [dbo].[Blogs] (2     [BlogId] INT            IDENTITY (1, 1) NOT NULL,3     [Name]   NVARCHAR (200) NULL,4     [Url] NVARCHAR(200) NULL, 5     CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)6 );
      View Code  

以及新建資料表Posts

       
 1 CREATE TABLE [dbo].[Posts] ( 2     [PostId]  INT            IDENTITY (1, 1) NOT NULL, 3     [Title]   NVARCHAR (MAX) NULL, 4     [Content] NVARCHAR (MAX) NULL, 5     [BlogId]  INT            NOT NULL, 6     CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([PostId] ASC), 7     CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE 8 ); 9 10 11 GO12 CREATE NONCLUSTERED INDEX [IX_BlogId]13     ON [dbo].[Posts]([BlogId] ASC);
      View Code  

3.3 建立一個控制檯專案(名稱如:CodeFirstExistingDatabaseSample)

 

3.4 在專案CodeFirstExistingDatabaseSample上右鍵單擊—》選單中會有“Entity Framework”選項—》選擇Reverse Engineer Code First,輸入相應的資料庫地址,使用者名稱、密碼、要操作的資料庫等資訊,確定即可。(前提是要安裝好Power Tools 外掛)

 

3.5 資料遷移,此功估計EF還暫未實現,從使用工具Entity Framework Power Tools Betas3 以及使用的Entity Framework 6.0.0-beta1來看,估計這是EF 6.0的功能 

 

四、資料庫生成位置可控制(其實主要就是DbContext的建構函式)

 

1.使用DbContext的建構函式:public DbContext(string nameOrConnectionString)

 

a、在app.config中新增:

    
1   <connectionStrings>2     <add name="CodeFirstBlogContext" providerName="System.Data.SqlClient" connectionString="Server=.;Database=CodeFirstBlog;uid=sa;pwd=sa" />3   </connectionStrings>
     

b、在資料上下文類中新增建構函式(原來沒有顯示出現,呼叫預設的一般是本機.\sqlexpress資料庫例項)

    
1         public BlogContext(string config)2             : base(config)3         {4         }
   

這裡可以顯示的引用配置檔案中的配置庫,注:此處config可以直接寫name=CodeFirstBlogContext,是配置檔案中的connectionStrings下的name。

 

2. 使用DbContext的建構函式:public DbContext(DbConnection existingConnection, bool contextOwnsConnection)

 

a、在資料上下文類中新增建構函式(原來沒有顯示出現,呼叫預設的一般是本機.\sqlexpress資料庫例項)

    
1 public BlogContext(DbConnection connection,bool contextOwnsConnection)2             : base(connection, contextOwnsConnection) 3         { }
   

b、使用時建立一個Connection即可

       
 1             string connStr = "Server=.;Database=CodeFirstBlog2;uid=sa;pwd=sa"; 2             using (SqlConnection conn = new SqlConnection(connStr)) 3             { 4                 using (var db = new BlogContext(conn, false)) 5                 { 6                     Console.WriteLine("輸入一個新的Blog名稱"); 7                     var name = Console.ReadLine(); 8  9                     var blog = new Blog { Name = name };10                     db.Blogs.Add(blog);11                     db.SaveChanges();12 13                     var query = from b in db.Blogs14                                 orderby b.Name15                                 select b;16 17                     foreach (var item in query)18                     {19                         Console.WriteLine(item.Name);20                     }21                 }22             }23             Console.ReadKey();
      View Code  

3. 使用資料的連線工廠

    
1             Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Server=.\sqlexpress;Database=CodeFirstBlog4;uid=sa;pwd=sa");2             using (var db=new BlogContext())3             {4                 db.Database.Initialize(true);5                 db.Blogs.Add( new Blog { Name = "test" });6                 db.SaveChanges();7             }
   

注:這裡指定資料庫名稱無效,應該與Database的Initialize方法有關,待查證。

 

  4.這裡還有其他的DbContext建構函式可用,可直接檢視DbContext類的實現。