Entity Framework Core 初體驗

昨天,我們稍微體會了,為了解決某個領域上的問題,針對描述該問題(具體化該問題的行為模式)而設計出資料模型(Data Model),該資料模型在商業行為中所產生的數據需要儲存,並於適當情況被讀取、修改和刪除。

這些資料庫操作的新增、修改、刪除、查詢,一般稱為資料存取層,今天就先來學習如何將先前設計的《地址》物件對應到資料庫的資料表。

安裝 NuGet 封裝套件

先開啟 NuGet 封裝管理員,為 Demae.Data 專案安裝合適的套件:

領域物件本身並不知道要如何被儲存,甚至連儲存在何種資料庫平台也不知道。這些是在資料存取層中決定,因為我們決定使用 SQL 資料庫,並以 Entity Framework Core 來實作資料存取,所以要安裝 Microsoft.EntityFrameworkCore.SqlServer:

接著也要安裝 Microsoft.EntityFrameworkCore.Tools 以便能在套件管理器主控台中,操作對資料庫的資料表建立和修改:

DbContext

在實作 DbContext 物件之前,因為資料存取層需要使用在 Demae.Domain 專案中所設計的領域物件,所以要先將 Demae.Domain 專案加入參考:

接著在 Demae.Data 專案內新增一個類別,就命名為 DemaeContext.cs 好了,並加入如下的程式碼:

using Demae.Domain;
using Microsoft.EntityFrameworkCore;

namespace Demae.Data
{
    public class DemaeContext : DbContext
    {
        public DemaeContext(DbContextOptions<DemaeContext> options) 
             : base(options) { }       
        
        public DbSet<City> Cities { get; set; }
        public DbSet<Area> Areas { get; set; }
        public DbSet<Address> Addresses { get; set; }
    }
}

上述的程式碼解釋如下:

使用 Entity Framework 功能來操作 Domain Model 的類別是繼承 DbContext 的資料內容類別(Data base Context Class),因此,這個類別(本案例是 DemaeDbContext)繼承 System.Data.Entity.DbContext基礎類別。

接下來的 public DemaeContext(DbContextOptions options) : base(options) { } 為建構函式。

接著的 public DbSet Cities { get; set; } 為包含到的領域物件,也可看成每一個領域物件要對應成資料庫的資料表,將來會隨著要寫的案子需要的領域物件的數目的增加而增加。

public DbSet Areas { get; set; } 和 public DbSet<Address> Addresses { get; set; } 也是相同的道理,因此,目前的程式碼會對應在資料庫中建立三個資料表:

  • Cites
  • Areas
  • Addresses

在 Web Api 專案中使用

DbContext 類別已經建立好了,接下來就是如何使用它來做資料的新增、修改、刪除、查詢的動作。因為該 DbContext 主要是要在 Web Api 專案中使用(以目前的案例),所以需要先在 Web Api 專案中設定該 DbContext 要如何被使用:

同樣地,因為 Web Api 專案需要使用到 Domain 和 Data 專案中所實作的成果,所以使用前必需先將該兩個專案加入參考:

接著在 Web Api 專案的 Startup.cs 中加入兩行程式碼,如下所示:

using Demae.Data;
using Microsoft.EntityFrameworkCore;

namespace Demae.WebApi
{
    public class Startup
    {
       .........
       .........
       .........

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            var connection = @"Server=keigen;Database=DemaeDb;Integrated Security=True;";
            services.AddDbContext<DemaeContext>(options => options.UseSqlServer(connection));

            services.AddMvc();
        }

        ........
        ........
        ........
    }
}

加入的程式碼的功用說明如下:

var connection = @"Server=keigen;Database=DemaeDb;Integrated Security=True;";

這行程式碼首先以一行字串(比較專業的說法叫做:連線字串)說明資料庫的連線的位置,其中  Server=keigen;是指定連線到命名為 keigen 這台資料庫伺服器(讀者要改成自己的),而 Database=DemaeDb 指定資料庫名稱為 DemaeDb (可以自行命名,阿源哥哥習慣是用方案名稱 + Db 當資料庫名稱)。

services.AddDbContext(options => options.UseSqlServer(connection));

為 Web Api 專案加入服務(service)並使用先前的連線字串連接 SQL Server 。

註:
連線字串的指定方式一般會有兩種,其中一種就是類似這次案例的直接在程式中指定,請種方式缺點是將來要更改資料庫時(開發階段與正式階段所使用的資料庫伺服器一定不一樣,就算是將來正式上線了,有時也有可能想要換資料庫伺服器供應商,而需要更換),沒有原始程式就無更改並重新編譯。

另一種方法是寫在可以在文字編輯器中開啟的設定檔中,只要更改字串內容即可,不需要重新編譯。此種做法會在往後的文章中討論。

好吧!今天就暫且學到這裡,明天再來學習資料庫轉移(Migrations)吧。