初次使用Entity Framework(以下簡稱EF),為了避免很快忘記,決定開日志記錄學習過程和遇到的問題。
因為項目比較小,只會用到EF的一些基本功能,因此先在此處制定一個學習目標:
1. 配置EF(指定EF用哪個數據庫,相信在大部分開發過程中都不會使用官方Demo中的LocalDb)
2. 根據代碼生成表(主要是一些特殊情況,比如希望自己設置string類型屬性的長度,不想統一都是nvarchar(max))
3. 生成視圖(部分類其實希望生成成為視圖,這樣可以讓數據庫表設計更加符合范式,同時簡化查詢,不知道能不能實現)
4. 生成數據庫腳本和變更腳本(對於Code First的方式來說,這一步也是相當重要的,否則就沒有Code First的意義了)
怎樣獲取EF,怎樣添加EF到項目里去這里就不說了,使用NuGet是一個相對簡單的方式,不清楚可以看官方的說明。添加完EF之后就需要對EF進行配置了,通常這時候配置文件里已經自動添加上默認的EF配置節點了,如果新建的是命令行程序,那配置文件應該就是這樣:

1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <configSections> 4 <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 5 <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 6 </configSections> 7 <entityFramework> 8 <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 9 <parameters> 10 <parameter value="v11.0" /> 11 </parameters> 12 </defaultConnectionFactory> 13 <providers> 14 <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 15 </providers> 16 </entityFramework> 17 </configuration>
可以看出配置文件的configSection中首先添加了一個名為entityFramework的section,下面接着多了一大篇 entityFramework的配置。defaultConnectionFactory項只會在沒有添加connectionString配置項的情 況下使用,默認值是LocalDbConnectionFactory,也就是使用LocalDb。我們可以將type改 為"System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework",這樣就可以使用SQL Server數據庫。parameter是SqlConnectionFactory的構造函數的參數,我們可以將它的值改為我們要指定的連接字符串,這 里可以使用標准的SQL Server連接字符串。需要注意的一點是,在這里Initial Catalog或Database項會被忽略。這里遇到了點小問題,不能指定數據庫名,難道只能使用默認生成的EFTest.DataContext作為 數據庫名么?通過對象瀏覽器找到System.Data.Entity.Infrastructure.SqlConnectionFactory類型, 查看帶參數的構造函數說明如下:
public SqlConnectionFactory(string baseConnectionString) System.Data.Entity.Infrastructure.SqlConnectionFactory 的成員 摘要: 使用給定的 BaseConnectionString 屬性創建新的連接工廠。 參數: baseConnectionString: 要用於“初始目錄”之外的數據庫的選項的連接字符串。 在調用 CreateConnection 時,將基於數據庫名稱在此字符串前預置“初始目錄”。 public System.Data.Common.DbConnection CreateConnection(string nameOrConnectionString) System.Data.Entity.Infrastructure.SqlConnectionFactory 的成員 摘要: 基於給定的數據庫名稱或連接字符串為 SQL Server 創建連接。如果給定的字符串包含“=”字符, 則將其視為一個完整的連接字符串,否則僅將其視為數據庫名稱。 參數: nameOrConnectionString: 數據庫名稱或連接字符串。 返回值: 已初始化的 DbConnection。
可以得知數據庫名稱是通過調用CreateConnection方法時獲得的。如果這時完成了官網上的最簡單的Code First的Demo,代碼里一定有一個父類為DbContext的BlogContext或者xxContext的類型。查看DbContext定義, 有一個構造函數參數名稱為string nameOrConnectionString,得解。只需要將代碼改為下面這樣就可以了:
1 public class BlogContext : DbContext 2 { 3 public BlogContext() 4 : base("你的數據庫名稱") 5 { 6 } 7 public DbSet<Blog> Blogs { get; set; } 8 public DbSet<Post> Posts { get; set; } 9 }
當然,也可以直接設置connectionStrings,就可以直接將defaultConnectionFactory配置項刪除了,也不需要代碼里指定數據庫名稱。
配置文件最終類似這個樣子:

1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <configSections> 4 <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 5 <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 6 </configSections> 7 <entityFramework> 8 <providers> 9 <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 10 </providers> 11 </entityFramework> 12 <connectionStrings> 13 <add name="BlogContext" 14 providerName="System.Data.SqlClient" 15 connectionString="Server=xxx;Database=xxx;Integrated Security=False;User ID=sa;Password=xxx;"/> 16 </connectionStrings> 17 </configuration>
最后補充說明一點,配置的數據庫連接字符串配置項的name應該與你的Context類型的名稱一致,例如本例中就應該配置為BlogContext,以避免其它額外的配置,至於能不能讓兩者不同,筆者暫時沒有研究,有興趣的朋友可以研究研究。