Blazor を扱った技術書として、増田智明さんの著書『Blazor 入門』があります。
本書では第 9 章から Entity Framework を用いたデータベースアクセスについて解説されますが、その導入として SQL Server データベースをローカル環境上に構築しています。
近年では Linux 環境で SQL Server が利用できるようになったので、Docker で上記の解説に必要な DB コンテナーを構築してみたいと思います。
前提確認
以下の方針に則り、コンテナーを構成します。
- SQL Server for Linux の Docker イメージを使って上記の用途をカバーする
- 本書の作業フローに極力影響を与えない
また、自分の開発環境の構成は以下の通りです。
PS > dotnet --list-sdks
5.0.401 [C:\Program Files\dotnet\sdk]
PS > docker --version
Docker version 20.10.10, build b485636
本書における開発環境は .NET Core 3.1 が想定されていますが、.NET 5 でも大きな違いはないと思われます。
コンテナー定義の作成
以下の docker-compose.yml
ファイルを作成します。
version: '3.4'
services:
mssql:
image: mcr.microsoft.com/mssql/server:2019-latest
environment:
ACCEPT_EULA: Y
SA_PASSWORD: P@ssw0rd!
ports:
- 1433:1433
volumes:
- "blazor-introduction-mssql:/var/opt/mssql"
- "./mssqlserver/ddl:/usr/src/ddl:ro"
volumes:
blazor-introduction-mssql:
コンテナーを起動する際は、以下のコマンドを実行します。
docker compose up mssql
コンテナー定義の解説
docker-compose.yml
の記載内容について、以下で解説します。
ベースイメージ
mssql:
image: mcr.microsoft.com/mssql/server:2019-latest
SQL Server 2019 のベースイメージ mcr.microsoft.com/mssql/server:2019-latest
を参照し、mssql
コンテナーとして定義しています。
環境変数
environment:
ACCEPT_EULA: Y
SA_PASSWORD: P@ssw0rd!
environment
の節に指定した環境変数は、それぞれ以下の意味を持ちます。
変数名 | 意味 |
---|---|
ACCEPT_EULA |
ライセンス条項への同意 |
SA_PASSWORD |
管理者アカウント (System Administrator) 用のログイン パスワード |
パスワードは DB へのログインの際に使用します。
使用ポートの指定
ports:
- 1433:1433
SQL Server が標準で使用するポート 1433
を、ホスト側のポートと対応させています。ホスト側で既にこのポートを使用している場合は、別のポートを指定する必要があります。
データベースの状態の保存
services:
mssql:
# ... 省略
volumes:
- "blazor-introduction-mssql:/var/opt/mssql"
# ... 省略
volumes:
blazor-introduction-mssql:
コンテナーを終了しても DB の状態が維持されるよう、/var/opt/mssql
以下のパスを、Docker ボリューム blazor-introduction-mssql
上で永続化する構成としています。
DDL ファイルの共有
volumes:
# ... 省略
- "./mssqlserver/ddl:/usr/src/ddl:ro"
コンテナー内のパス /usr/src/ddl
へ、テーブルを作成するための DDL ファイルをマウントしています。DDL ファイルはコンテナー側から変更を加えることはないため、:ro
フラグにより読み取り専用 (Read-Only) として宣言しています。
ホスト側で対応するパスは、ここでは相対参照により ./mssqlserver/ddl
として指定しました。ホスト側でこのパスに保存したファイルが、コンテナーからは /usr/src/ddl
以下に存在するものとして扱われます。
データベースの構成
データベースの作成
コンテナー起動後は、データベース blazordb
を作成する DDL を実行します。
以下の SQL を記述したファイルを database.sql
として、./mssqlserver/ddl
へ保存します。
EXECUTE AS LOGIN = 'sa'
GO
CREATE DATABASE blazordb
GO
これは管理者アカウント sa
でログインし、解説に用いるデータベース blazordb
を作成するクエリです。
docker compose exec
コマンドにより、コンテナー内で目的の DDL ファイルを実行します。
docker compose exec mssql /opt/mssql-tools/bin/sqlcmd -U SA -P P@ssw0rd! -i /usr/src/ddl/database.sql
テーブルの作成
続いて、データベース blazordb
上にテーブル books
を作成します。
この時に実行する DDL ファイルは以下の内容になります。管理者アカウント sa
により、先ほど作成したデータベース blazordb
へ接続し、テーブル books
を作成するクエリです。
EXECUTE AS LOGIN = 'sa'
GO
USE blazordb
GO
CREATE TABLE [dbo].[books]
(
[id] INT IDENTITY(1, 1) NOT NULL
, [title] NVARCHAR(50) NOT NULL
, [author] NVARCHAR(50) NOT NULL
, [price] INT NOT NULL
, [publisher] NVARCHAR(50) NULL
, CONSTRAINT [PK_books] PRIMARY KEY CLUSTERED
(
[id] ASC
) WITH (
PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
)
) ON [PRIMARY]
GO
これを books.sql
として保存し、コンテナー内で実行します。
docker compose exec mssql /opt/mssql-tools/bin/sqlcmd -U SA -P P@ssw0rd! -i /usr/src/ddl/books.sql
レコードの登録
レコードを登録する場合は、コンテナー側の CLI か、Visual Studio 上の SQL Server オブジェクト エクスプローラーを利用します。
CLI を利用する場合は、以下のコマンドによりサーバーへ接続します。
docker compose exec mssql /opt/mssql-tools/bin/sqlcmd -U SA -P P@ssw0rd!
以下の INSERT 文を実行し、レコードを登録します。
INSERT INTO [dbo].[books]
([id], [title], [author], [price], [publisher])
VALUES (1, N'タイトルA', N'著者A', 5000, N'出版社A')
GO
最終的に、以下のような books
レコードが登録された状態とします。
データベースへの接続
サーバーは Linux コンテナー上で稼働しており、Windows 認証は使用できません。そのため、接続文字列を SQL Server 認証 (ユーザー名とパスワードによる認証) へ変更します。
具体的には Models\blazordbContext.cs
へ記載する接続文字列を、以下の内容へ変更します。
if (!optionsBuilder.IsConfigured)
{
- optionsBuilder.UseSqlServer("Server=.;Database=blazordb;Trusted_connection=True");
+ optionsBuilder.UseSqlServer("Server=.;Database=blazordb;User ID=sa;Password=P@ssw0rd!");
}
変更前の文字列に含まれる Trusted_connection=True
が、DB への接続に Windows 認証を使用することを表しています。これを User ID
と Password
の 2 項目へ置き換えることで、SQL Server 認証により接続する構成となります。
SQL Server 認証を使用するのは、Entity Framework を用いたスキャフォールディング操作を行う場合も同様です。コマンドを実行する際の認証情報に、上記と同様のパラメータを指定します。
dotnet ef dbcontext scaffold "Server=.;Database=blazordb;User ID=sa;Password=P@ssw0rd!" Microsoft.EntityFrameworkCore.SqlServer -o Models
実行例
前述の通り Docker コンテナーを使用する場合は、接続文字列の指定に修正を加えるだけで対応が可能です。Blazor アプリケーションを実行した結果として、以下の内容が返されます。
SQL Server をホスト上にインストールしない場合でも、Docker を利用して対応可能であることが確認できたと思います。