一、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 改進了轉置模型的向導,使其更容易和更快地為查詢數據批量導入存儲過程。
1.4 參考文章、博文
http://msdn.microsoft.com/zh-cn/magazine/jj991973.aspx
http://msdn.microsoft.com/zh-cn/magazine/hh547106.aspx
http://blogs.msdn.com/b/jason_zander/archive/2012/07/30/entity-framework-code-first-asp-net-web-api.aspx
http://msdn.microsoft.com/zh-cn/magazine/hh126815.aspx
二、 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 }
2.4 建立數據上下文類
添加引用:using System.Data.Entity;並繼承DbContext
代碼示例:

1 public class BlogContext : DbContext 2 { 3 public DbSet<Blog> Blogs { set; get; } 4 public DbSet<Post> Posts { get; set; } 5 }
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.Blogs 11 orderby b.Name 12 select b; 13 14 foreach (var item in query) 15 { 16 Console.WriteLine(item.Name); 17 } 18 } 19 Console.ReadKey();
以上便是最基本的應用
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 Blog 2 { 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 }
輸入命令:Add-Migration AddUrl,同時在Migrations下會有201307080524348_AddUrl.cs文件
繼續輸入命令:Update-Database,更新數據庫
1.2 添加新的實體類文件User
1 public class User 2 { 3 public string UserName { get; set; } 4 public string DisplayName { get; set; } 5 }
輸入命令:Add-Migration AddUser;(注可能提示沒有主鍵,此時要為表User建立主鍵,先添加引用:using System.ComponentModel.DataAnnotations;)
1 public class User 2 { 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 Blog 2 { 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 );
以及新建數據表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 GO 12 CREATE NONCLUSTERED INDEX [IX_BlogId] 13 ON [dbo].[Posts]([BlogId] ASC);
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>
注:當然這里也可以添加使用其他數據庫,但是要提起安裝好驅動:引用可參考此文:http://www.cnblogs.com/yylp521/p/3173176.html
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.Blogs 14 orderby b.Name 15 select b; 16 17 foreach (var item in query) 18 { 19 Console.WriteLine(item.Name); 20 } 21 } 22 } 23 Console.ReadKey();
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類的實現。