0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EfCoreプロバイダー変更

Posted at

はじめに

Azure SQL Database ではサブスクリプションごとに1つ無料で SQL Server を作成することができます。学習のため個人開発していたプロジェクトで使用していたのですが、この度完成し次のプロジェクトに取り掛かる際に接続先 DB を SQLite に変更しました。

その際に EFCore の接続先プロパイダーの切り替え作業が発生したため、その手順をまとめます。

今回は SQL Server →SQLite で解説しますが、同じ方法で切り替えが可能です。

修正方法

以下の順番に対応をしてください。

  1. DBContext の修正
  2. Nuget から対象プロパイダーの EFCore パッケージを取得
  3. Program.csの修正
  4. appsetting.jsonの修正

DBContext の修正

EFCore でプロパイダーを変更する際には大きく分けて2つの方法があります。

  1. SQL Server 用とは別に SQLite 用の DBContext を作成して接続する。
  2. 既存の Migrations 履歴を削除して新しく Migrations を実施する。

1つ目の方法では SQL Server 用と SQLite 用の DBContext が別々に存在するため段階的な移行も可能です。またこちらの方法では Migration 履歴を残したまま移行することができます。

ただし SQL Server の DBContext をコード上で使用している箇所すべてで使用している DBContext を変更する必要があり、コードの修正量は多くなる傾向があります。

2つ目の方法は既存の Migration 履歴をすべて削除もしくはコメント化して初期化する事です。

削除を行う理由はAdd-Migration時に出力されるコードにプロパイダー固有の記載が含まれているためです。そのままの状態で純粋に接続先を切り替えるだけではマイグレーションの適用時にエラーになってしまいます。

SQLiteでテーブル追加時のMigration履歴
protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "StudyRecords",
        columns: table => new
        {
            Id = table.Column<int>(type: "INTEGER", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),// SQLite固有の書き方
            Title = table.Column<string>(type: "TEXT", nullable: false),
            StudyTime = table.Column<int>(type: "INTEGER", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_StudyRecords", x => x.Id);
        });
}

上記の例ですと ID 列の設定時にSqlite:Autoincrementというアノテーションを使用しています。この書き方は他のプロパイダー接続時には当然エラーになります。

この方法のメリットは修正範囲が少ない事です。それまで使用していた DBContext の接続先が変わっているためそのまま使用することができます。

ただし履歴の削除もしくはコメント化が必要な点。一度にすべて修正が必要な点がデメリットとして挙げられます。

Nuget から対象プロパイダーの EFCore パッケージを取得

Nuget より対象プロパイダーのパッケージをインストールしてください。SQLite の場合はMicrosoft.EntityFrameworkCore.Sqliteです。

この時にすでにインストールされているMicrosoft.EntityFrameworkCoreパッケージのバージョンと同じバージョンをインストールすると安全です。

.net8 のプロジェクトでスキャフォールディングを使用すると Nuget パケージは 8.x.x の物がインストールされます。SQLite 用の EFCore パッケージの最新版(2025/1/18)をインストールすると 9.x.x がインストールされ、この状態でUpdate-Databaseを実行するとエラーになります。

パッケージのバージョンを合わせると正常に動作しました。

Program.cs の修正

DBContext を登録している部分のメソッドをUseSqlServer()からUserSqlite()にします。

builder.Services.AddDbContextFactory<BlazorApp12Context>(options =>
-    options.UseSqlServer(builder.Configuration.GetConnectionString("SampleAppContext") ?? throw new InvalidOperationException("Connection string 'SampleAppContext' not found.")));
+    options.UseSqlite(builder.Configuration.GetConnectionString("SampleAppContext") ?? throw new InvalidOperationException("Connection string 'SampleAppContext' not found.")));

DBContext を別々に用意する場合はそれぞれ既存の登録処理の削除は不要です。

appsetting.json の修正

コネクションストリングを SQLite 用に修正します。

  "ConnectionStrings": {
    "SampleAppContext": "Data Source=SampleAppContext-fac68bf8-83d6-46cb-b942-a4d58b8f1e2d.db"
  }

Migration の実行

ここまでの対応を実行後にAdd-MigrationおよびUpdate-Databaseコマンドを実行してマイグレーションの適用を行うと SQLite をアプリケーションから使用することができます。

おわりに

EFCore でのプロパイダー変更の方法についてまとめました。

個人開発をしていくなかで自分のように Azure SQL Database を利用している方だとプロパイダー変更をしたくなるようなケースは多いと思います。そういった方の助けになれればうれしいです。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?