SQLite EF Core データベース プロバイダーの制限事項

SQLite プロバイダーには、移行に関していくつかの制限事項があります。 これらの制限事項の多くは、基になる SQLite データベース エンジンでの制限事項の結果であり、EF に固有のものではありません。

モデリングの制限事項

共通リレーショナル ライブラリ (EF Core リレーショナル データベース プロバイダーによって共有) では、ほとんどのリレーショナル データベース エンジンに共通する概念をモデル化するための API が定義されています。 これらの概念のいくつかは、SQLite プロバイダーによってサポートされていません。

  • スキーマ
  • シーケンス
  • データベースで生成されたコンカレンシー トークン (ドキュメントを参照)

クエリの制限事項

SQLite では、次のデータ型はネイティブにサポートされていません。 EF Core ではこれらの型の値に関して読み取りと書き込みを行うことができます。また、等しいかどうかのクエリ (where e.Property == value) もサポートされています。 ただし、比較や順序付けなどの他の操作では、クライアントでの評価が必要になります。

  • DateTimeOffset
  • decimal
  • TimeSpan
  • ulong

DateTimeOffsetの代わりに、DateTime 値を使用することをお勧めします。 複数のタイム ゾーンを処理する場合は、値を保存する前に UTC に変換してから、適切なタイム ゾーンに再び変換することをお勧めします。

decimal 型では、高レベルの精度が提供されます。 ただし、そのレベルの精度が必要ない場合は、代わりに double を使用することをお勧めします。 値コンバーター を使用して、クラスで decimal を引き続き使用できます。

modelBuilder.Entity<MyEntity>()
    .Property(e => e.DecimalProperty)
    .HasConversion<double>();

移行に関する制限事項

SQLite データベース エンジンでは、他の大多数のリレーショナル データベースでサポートされているいくつかのスキーマ操作がサポートされていません。 サポートされていない操作のいずれかを SQLite データベースに適用しようとすると、NotSupportedException がスローされます。

特定の操作を実行するためにはリビルドが試行されます。 リビルドが可能なのは、EF Core モデルの一部であるデータベース成果物に対してのみです。 データベース成果物がモデルの一部でない場合 (たとえば、移行の中で手動で作成された場合)、NotSupportedException が発生します。

操作 サポート対象?
AddCheckConstraint ✔ (リビルド)
列を追加
AddForeignKey ✔ (リビルド)
AddPrimaryKey ✔ (リビルド)
AddUniqueConstraint (ユニーク制約を追加) ✔ (リビルド)
AlterColumn ✔ (リビルド)
CreateIndex
テーブル作成
制約チェックを削除 ✔ (リビルド)
列を削除 ✔ (リビルド)
DropForeignKey ✔ (リビルド)
DropIndex
主キー削除 ✔ (リビルド)
DropTable
DropUniqueConstraint ✔ (リビルド)
列の名前を変更
インデックス名変更 ✔ (リビルド)
RenameTable(テーブル名変更)
EnsureSchema ✔ 変更なし
DropSchema ✔ (no-op)
挿入
更新
削除

移行に関する制限事項の回避策

リビルドを実行するために移行でコードを手動で記述することによって、これらの制限事項の一部を回避できます。 テーブルのリビルドには、新しいテーブルの作成、新しいテーブルへのデータのコピー、古いテーブルの削除、新しいテーブルの名前変更が必要です。 これらの手順の一部を実行するには、Sql メソッドを使用する必要があります。

詳細については、SQLite のドキュメントで、他の種類のテーブル スキーマ変更を行う方法に関する記事を参照してください。

べき等スクリプトの制限事項

他のデータベースとは異なり、SQLite には手続き型の言語が含まれていません。 このため、べき等移行スクリプトに必要な if-thenのロジックを生成する手段がありません。

データベースに適用された最後の移行がわかっている場合は、その移行から最新の移行にスクリプトを生成できます。

dotnet ef migrations script CurrentMigration

それ以外の場合は、dotnet ef database update を使用して移行を適用することをお勧めします。 このコマンドを実行するときにデータベース ファイルを指定できます。

dotnet ef database update --connection "Data Source=My.db"

同時移行の保護

EF9 では、同時移行の実行から保護するための移行 ロック メカニズム が導入されました。 接続が閉じると自動的に解放されるセッション レベルのアプリケーション ロック (sp_getapplock) を使用するSQL Serverとは異なり、SQLite には組み込みのアプリケーション ロックがありません。 代わりに、EF Core は __EFMigrationsLock テーブルを作成し、ロックを取得する行を挿入します。

破棄されたロックの処理

アプリケーションが予期せず終了した場合 (移行中にプロセスが強制終了された場合など)、 __EFMigrationsLock テーブルのロック行がクリーンアップされない可能性があります。 これにより、以降の移行は完了しません。各試行はロックが解放されるまで無期限に待機するためです。

破棄されたロックを解決するには、 __EFMigrationsLock テーブルをデータベースから削除します。

DROP TABLE "__EFMigrationsLock";

または、テーブルからすべての行を削除します。

DELETE FROM "__EFMigrationsLock";

ロックをクリアした後、以降の移行操作は正常に続行されます。 テーブルは、必要に応じて自動的に再作成されます。

関連項目