Entity Framework 6 Code-based Configuration

by Vivid 4. 十一月 2015 05:33

.NET Magazine國際中文電子雜誌
者:許薰尹
稿:張智凱
文章編號:N151116501
出刊日期:2015/11/4
開發工具:Visual Studio 2013 Ultimate Update 4
版本:.NET Framework 4.5.x

Entity Framework 6版新增一個技術,稱之為Code-based Configuration,意思是使用程式碼來設定Entity Framework的組態設定。在這項技術未推出之前,只能利用組態檔案來進行設定的動作,現在你可以使用程式的方式來進行設定。不過要特別注意的是,組態檔和程式碼若做了相同的設定動作,組態檔的設定優先權會高於程式的設定。

為了說明,我們先來看一下預設使用組態檔設定的方式。以下建立一個主控台應用程式(Console Application),請參考下圖所示:

clip_image002

圖 1:建立主控台應用程式(Console Application)。

接著在專案中,使用Nuget Package Manager安裝Entity Framework套件:

install-package entityframework -version 6.1.3

加入一個MyDBContext 類別,繼承DbContext 負責存取資料庫,其中包含一個Employees 屬性:

namespace CodeBaseConfig {
  public class MyDBContext : DbContext {
    public DbSet<Employee> Employees { get; set; }
  }
}

Employees 類別定義如下:

 

namespace CodeBaseConfig {
  public class Employee {
    public int EmployeeID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
  }
}

 

 

加入一個MyDbInitializer類別來初始化Employee資料表,當資料表被建立時,新增三筆資料到資料庫:

 

namespace CodeBaseConfig {
  class MyDbInitializer : DropCreateDatabaseAlways<MyDBContext> {
    protected override void Seed( MyDBContext context ) {
      context.Employees.Add( new Employee( ) {
        Name = "Mary" ,
        Age = 30
      } );
 
      context.Employees.Add( new Employee( ) {
        Name = "Candy" ,
        Age = 50
      } );
      context.Employees.Add( new Employee( ) {
        Name = "LiLi" ,
        Age = 40
      } );
 
      context.SaveChanges( );
    }
  }
}

 

在Main方法中,叫用Database.SetInitializer方法初始化資料,接著下查詢將資料表筆數顯示在畫面上:

 

namespace CodeBaseConfig {
  class Program {
    static void Main( string[ ] args ) {
       Database.SetInitializer( new MyDbInitializer());
       MyDBContext db = new MyDBContext( );
      var result = db.Employees.ToList( );
       Console.WriteLine( result.Count().ToString());
       Console.ReadLine( );
    }
  }
}

 

 

 

預設在你安裝Entity Framework時,專案中的app.config檔案將自動加入以下entityFramework的組態設定:

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

 

 

 

按F5執行程式,將印出以下畫面,顯示資料庫資料有三筆:

clip_image004

圖 2:範例執行結果。

目前根據組態檔案的定義,資料庫存在SQL Server Express之中。以下是SQL Server 管理工具看到的畫面,請參考下圖所示:

clip_image006

圖 3:資料建立在SQL Server Express。

若修改組態檔案,修改defaultConnectionFactory的組態設定如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

 

再次執行程式碼,這次會建立在(localdb)\v11.0資料庫之中,請參考下圖所示:

clip_image008

圖 4:資料庫建立在(localDB)。

使用以程式為基礎的組態設定- (localdb)

Entity Framework 6 以程式為基礎的組態設定(Code-based Configuration)乃是採用一個繼承System.Data.Entity.Config.DbConfiguration的子類別來達成。若要使用以程式為基礎的組態設定功能,建議注意以下事項:

  • 一個應用程式中,只包含一個DbConfiguration類別。
  • 將DbConfiguration類別和DbContext類別的程式碼放在相同的組件(Assembly)之中。
  • 為DbConfiguration類別定義一個public,且無參數的建構函式(Constructor)。
  • 在DbConfiguration類別的建構函式(Constructor)之中,叫用DbConfiguration類別的方法來進行設定。

我們來看一下做法,首先修改上例程式碼的組態檔案,移除< entityFramework>區段的設定,目前的程式碼看起來如下所示:

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>
</configuration>

 

在專案之中加一個MyConfiguration類別,繼承DbConfiguration類別,在其建構函式之中,叫用SetExecutionStrategy與SetDefaultConnectionFactory方法,設定使用 (localDB)當做資料庫:

 

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace CodeBaseConfig {
  public class MyConfiguration : DbConfiguration {
    public MyConfiguration( ) {
      SetExecutionStrategy( "System.Data.SqlClient" , ( ) => new DefaultExecutionStrategy( ) );
      SetDefaultConnectionFactory( new LocalDbConnectionFactory( "v11.0" ) );
    }
  }
}

 

 

 

套用DbConfiguration類別的方式有兩種:

  • 使用Attribute套用組態。
  • 在Config檔案套用組態。

使用Attribute套用組態 - (localdb)

我們看一下使用Attribute套用組態的方法,首先修改MyDBContext 類別,在類別上方套用DbConfigurationTypeAttribute,例如以下程式碼所示:

namespace CodeBaseConfig {
  [DbConfigurationType( typeof( MyConfiguration ) )]
  public class MyDBContext : DbContext {
    public DbSet<Employee> Employees { get; set; }
  }
}

Main主程式程式碼目前看起來如下:

namespace CodeBaseConfig {
  class Program {
    static void Main( string[ ] args ) {
      Database.SetInitializer( new MyDbInitializer( ) );
      MyDBContext db = new MyDBContext( );
      var result = db.Employees.ToList( );
      Console.WriteLine( result.Count().ToString());
      Console.ReadLine( );
    }
  }
}

 

程式執行後,檢視資料庫,目前將建立在(LocalDB) ,請參考下圖所示:

clip_image010

圖 5:資料庫建立在(localdb)。

在組態檔案套用組態 - (localdb)

第二種做法是組態檔案套用,先刪掉或註解MyDBContext  類別DbConfigurationTypeAttribute的設定:

 

namespace CodeBaseConfig {
  //[DbConfigurationType( typeof( MyConfiguration ) )]
  public class MyDBContext : DbContext {
    public DbSet<Employee> Employees { get; set; }
  }
}

 

 

修改app.config組態檔案,加入< entityFramework>設定,設定codeConfigurationType,前半段是DbConfiguration類別的完整名稱(含命名空間),逗號後是DbConfiguration類別所在的組件名稱:

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>

  <entityFramework codeConfigurationType="CodeBaseConfig.MyConfiguration, CodeBaseConfig">
  </entityFramework>
 
</configuration>

 

使用以程式為基礎的組態設定- (SQL Server Express)

若想使用以程式為基礎的組態設定,將資料指定到SQL Server Express,套用DbConfiguration類別的方式有兩種:

  • 使用Attribute套用組態。
  • 在Config檔案套用組態。

使用Attribute套用組態- (SQL Server Express)

接下來我們來談一下,使用Attribute套用組態的方法,將資料庫放在SQL Server Express的做法。修改DbConfiguration類別,建立SetDefaultConnectionFactory物件,傳入SetDefaultConnectionFactory方法:

 

namespace CodeBaseConfig {
  public class MyConfiguration : DbConfiguration {
    public MyConfiguration( ) {
      SetExecutionStrategy( "System.Data.SqlClient" , ( ) => new DefaultExecutionStrategy( ) );
       SetDefaultConnectionFactory( new SqlConnectionFactory( ) );
    }
  }
}

 

 

修改MyDBContext 類別,在類別上方套用DbConfigurationTypeAttribute,例如以下程式碼所示:

 

namespace CodeBaseConfig {
  [DbConfigurationType( typeof( MyConfiguration ) )]
  public class MyDBContext : DbContext {
    public DbSet<Employee> Employees { get; set; }
  }
}

 

 

修改app.config組態檔案,移除< entityFramework>設定,目前組態檔案的內容看起來如下:

 

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>
 
</configuration>

 

 

在組態檔案套用組態 - (SQL Server Express)

若要使用組態檔案來套用設定,那麼先確定DbConfiguration類別的程式如下,建立SetDefaultConnectionFactory物件,傳入SetDefaultConnectionFactory方法:

namespace CodeBaseConfig {
  public class MyConfiguration : DbConfiguration {
    public MyConfiguration( ) {
      SetExecutionStrategy( "System.Data.SqlClient" , ( ) => new DefaultExecutionStrategy( ) );
 
      SetDefaultConnectionFactory( new SqlConnectionFactory( ) );
    }
  }
}

 

刪掉或註解MyDBContext  類別DbConfigurationTypeAttribute的設定:

 

namespace CodeBaseConfig {
  public class MyDBContext : DbContext { 
    public DbSet<Employee> Employees { get; set; }
  }
 
}

 

 

 

修改app.config組態檔案,加入< entityFramework>設定,設定codeConfigurationType,前半段是DbConfiguration類別的完整名稱(含命名空間),逗號後是DbConfiguration類別所在的組件名稱:

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>
  <entityFramework codeConfigurationType="CodeBaseConfig.MyConfiguration, CodeBaseConfig">
  </entityFramework>
 
</configuration>

 

 

 

設定資料庫提供者(Database Provider)

以程式為基礎的組態設定方式還可以用來設定資料庫提供者(Database Provider),只要在DbConfiguration類別中叫用SetProviderServices方法,以下範例程式碼會將資料庫建立在SQL Server Express。

 

 

namespace CodeBaseConfig {
  public class MyConfiguration : DbConfiguration {
    public MyConfiguration( ) {
      SetExecutionStrategy( "System.Data.SqlClient" , ( ) => new DefaultExecutionStrategy( ) );
      SetDefaultConnectionFactory( new SqlConnectionFactory( ) );
      SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
    }
  }
}

 

 

以上程式的設定,就等同於在組態檔案中加入以下的設定:

 

 

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

 

 

 

設定初始化資料庫的類別

以程式為基礎的組態設定方式還可以用來設定設定初始化資料庫的類別,修改DbConfiguration類別,叫用SetDatabaseInitializer方法,傳入MyDbInitializer物件到其建構函式:

namespace CodeBaseConfig {
  public class MyConfiguration : DbConfiguration {
    public MyConfiguration( ) {
      SetExecutionStrategy( "System.Data.SqlClient" , ( ) => new DefaultExecutionStrategy( ) );
      SetDefaultConnectionFactory( new SqlConnectionFactory( ) );
      SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
      SetDatabaseInitializer( new MyDbInitializer( ) );
    }
  }
}

 

在DbContext 類別套用此設定,並移除app.config組態檔案中 < entityFramework>的設定:

 

  [DbConfigurationType( typeof( MyConfiguration ) )]
public class MyDBContext : DbContext {
  public MyDBContext( )
    : base( ) {
 
  }
  public DbSet<Employee> Employees { get; set; }
}

 

 

這樣主程式就不用呼叫Database.SetInitializer方法來進行初始化:

 

namespace CodeBaseConfig {
  class Program {
    static void Main( string[ ] args ) {
 
     // Database.SetInitializer( new MyDbInitializer());
 
      MyDBContext db = new MyDBContext( );
      var result = db.Employees.ToList( );
 
      Console.WriteLine( result.Count().ToString());
 
      Console.ReadLine( );
    }
  }
}

 

 

使用組態檔案初始化資料表

最後,我們看一下如何使用組態檔案初始化資料表,設定DbConfiguration類別如下:

 

public class MyConfiguration : DbConfiguration {
  public MyConfiguration( ) {
    SetExecutionStrategy( "System.Data.SqlClient" , ( ) => new DefaultExecutionStrategy( ) );
    SetDefaultConnectionFactory( new SqlConnectionFactory( ) );
  }
}

 

 

在DbContext類別設定DbConfigurationTypeAttribute:

 

public class MyDBContext : DbContext {
  public MyDBContext( )
    : base( ) {
 
  }
  public DbSet<Employee> Employees { get; set; }
}

 

 

在app.config組態檔案,加入< entityFramework>設定,加入<context>與<databaseInitializer>指定DbContext與databaseInitializer   :

 

<entityFramework codeConfigurationType="CodeBaseConfig.MyConfiguration, CodeBaseConfig">
  <contexts>
    <context type="CodeBaseConfig.MyDBContext, CodeBaseConfig"  >
      <databaseInitializer   type="CodeBaseConfig.MyDbInitializer, CodeBaseConfig">
      </databaseInitializer>
    </context>
  </contexts>
</entityFramework>

Tags:

.NET Magazine國際中文電子雜誌 | Entity Framework | 許薰尹Vivid Hsu

不允許評論

NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List