我們現在有了基本的日誌,但是每次輸入完重新載入頁面數據都會重置,因為這些數據都只存在於瀏覽器,沒有真正儲存到資料庫,為了保存下來,我們要跟資料庫連接。
(註:Blazor WebAssembly 沒有直接跟資料庫互動的能力,不過微軟有提供ASP.NET Core hosted 選項,可以在建立 Blazor WebAssembly 時一併建立 ASP.NET Core Web API 專案)
Entity Framework Core
首先在appsettings.json加入連線字串,因為測試用,所以 SqlServer 用本地資料庫。
{
"ConnectionStrings": {
"DBConnection": "Server=(localdb)\\MSSQLLocalDB;database=Blog;integrated security=true;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
接著 NuGet 下載兩個元件,分別為Microsoft.EntityFrameworkCore.SqlServer 跟Microsoft.EntityFrameworkCore.Tools,這兩個元件是跟 SqlServer 互動用的 ORM 元件,ORM 又是什麼呢?
專案工程組態檔:BlazorServer.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
遠古時代的程式開發者想從SqlServer 取資料回來,都必須學習SQL 語句,後來.NET 平台(包括VB、C#)開發了ADO.NET 這個取資料的好工具,將資料取回來後一一跟程式mapping,但ADO.NET 在資料映射上不如人意,微軟便推出了Entity Framework,這就是初始的ORM(Object-Relational Mapper),讓開發者可以把資料變成實體(entity),不用實際去接觸SQL 語句,且有了設計工具(Designer) 讓程式開發者更好操作。
但也有些人覺得Entity Framework 太笨重就轉向另一個輕便的工具Dapper的懷抱,筆者也用過Dapper,如果是喜歡自己組SQL 語句的人確實會覺得方便。
而.NET Core 這個跨平台版本的ORM 就是用Entity Framework Core 去做資料映射的處理。
安裝完元件後,新增一個類別 AppDbContext,繼承DbContext,裡面的建構函式將DbContextOptions<AppDbContext> options傳給基底類別 也就是DbContext。
AppDbContext.cs
using Microsoft.EntityFrameworkCore;
namespace BlazorServer.Models;
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<BlogModel>? Blogs { get; set; }
public DbSet<PostModel>? Posts { get; set; }
}
接著打開Program.cs,註冊使用資料庫,這邊用的是UseSqlServer(),當然也有UseMysql()、UseOracle()可以用,只要安裝對應的元件即可。

打開套件管理器主控台,輸入命令Add-Migration Init,告訴Entity Framework Core 要建立一個資料庫遷移,接著就會產生遷移目錄Migration,這是Entity Framework Core 的特點,在程式跟資料庫之間產生中介Migration,另外Migration 一大好處就是在真正確定前,都可以不斷修改,等確定後再更新資料庫。


Relation between Blog and Post
接下來要在Post 裡面加上BlogId,Blog 對於Post 而言是主表之於子表,如果新增遷移的時候沒有加入對主表的關聯(也就是主表外鍵關聯子表),EF Core 很聰明會主動加上,但欄位名就會是Model+Key 的名稱,變成BlogModelBlogId,我們來把名稱簡化。

先在PostModel加上兩個屬性,BlogId跟Blog,切記一定要這樣添加,BlogId是存在資料庫用的,Blog則是在關聯資料的時候有個實體可以用,讓我們不用自己 join 資料表,後續會再說明。

接著用Remove-Migration將原先的 Migration 清除,再新增一次 Migration,即執行命令Add-Migration Init,可以看到新的 Migration 有簡化的名稱BlogId了,這時候再去更新資料庫。

使用命令Update-Database去更新資料庫,然後打開SQL Server 物件總管,可以找到剛才建立的資料庫Blog,資料庫名來自連線字串database的名稱,可以看到資料庫已經建起來了,過程中沒有用到 SQL 語句或是 SSMS 介面。


不過有一點要特別注意,中途如果換資料庫的話,原先的 Migration 有很大機率產生問題,各家資料庫的資料型別都有差異,所以最好一開始就規劃好用哪個資料庫。
除了AddDbContext<T>這種最常見的做法,還有AddDbContextFactory<T>這種在個別元件產生新的DbContext的方法,因為AddDbContext<T>的生命週期是scoped,對 Blazor Server 來說也就是除非關閉系統,否則DbContext都不會 dispose,有些人希望生命週期僅限於元件即可,就可以用AddDbContextFactory<T>。
參考:
註:本文程式碼透過 .NET 6 + Visual Studio 2022 重構,可點擊原文連結與重構後程式碼比較學習,謝謝閱讀,支援原作者