基本的なログは得られるようになりましたが、毎回入力後にページをリロードするとデータがリセットされてしまいます。これはデータがブラウザ上にしか存在せず、実際にデータベースに保存されていないためです。データを永続化するために、データベースに接続する必要があります。
(注:Blazor WebAssembly はデータベースと直接やりとりする機能を持っていませんが、Microsoft は 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 から2つのパッケージ 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 というデータ取得の優れたツールを開発し、データを取得した後、プログラムと一対一で マッピング していました。しかし ADO.NET のデータマッピングは期待通りではなく、Microsoft は Entity Framework をリリースしました。これが初期の ORM(Object-Relational Mapper) であり、開発者はデータを エンティティ として扱い、実際に 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 の大きな利点は、確定する前であれば何度でも修正でき、確定後にデータベースを更新できることです。


Blog と Post の関係
次に Post に BlogId を追加します。Blog は Post に対して 主テーブル であり 子テーブル です。マイグレーションを追加する際に主テーブルとの関連(つまり主テーブルの外部キーが子テーブルを参照する)を追加していなくても、EF Core は賢く自動的に追加しますが、その場合のフィールド名は Model+Key の形式(BlogModelBlogId)になります。そこで名前を簡略化しましょう。

まず PostModel に2つのプロパティ 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 は破棄されません。ライフサイクルをコンポーネントのみに限定したい場合には、AddDbContextFactory<T> を使用できます。
参照:
注:この記事のコードは .NET 6 + Visual Studio 2022 でリファクタリングされています。原文リンクとリファクタリング後のコードを比較して学習できます。ご愛読ありがとうございます。原作者をサポートしてください。