SQLite プロバイダーには、移行に関していくつかの制限事項があります。 これらの制限事項の多くは、基になる SQLite データベース エンジンでの制限事項の結果であり、EF に固有のものではありません。
モデリングの制限事項
共通リレーショナル ライブラリ (EF Core リレーショナル データベース プロバイダーによって共有) では、ほとんどのリレーショナル データベース エンジンに共通する概念をモデル化するための API が定義されています。 これらの概念のいくつかは、SQLite プロバイダーによってサポートされていません。
- スキーマ
- シーケンス
- データベースで生成されたコンカレンシー トークン (ドキュメントを参照)
クエリの制限事項
SQLite では、次のデータ型はネイティブにサポートされていません。 EF Core ではこれらの型の値に関して読み取りと書き込みを行うことができます。また、等しいかどうかのクエリ (where e.Property == value) もサポートされています。 ただし、比較や順序付けなどの他の操作では、クライアントでの評価が必要になります。
DateTimeOffsetdecimalTimeSpanulong
DateTimeOffsetの代わりに、DateTime 値を使用することをお勧めします。 複数のタイム ゾーンを処理する場合は、値を保存する前に UTC に変換してから、適切なタイム ゾーンに再び変換することをお勧めします。
decimal 型では、高レベルの精度が提供されます。 ただし、そのレベルの精度が必要ない場合は、代わりに double を使用することをお勧めします。 値コンバーター を使用して、クラスで decimal を引き続き使用できます。
modelBuilder.Entity<MyEntity>()
.Property(e => e.DecimalProperty)
.HasConversion<double>();
移行に関する制限事項
SQLite データベース エンジンでは、他の大多数のリレーショナル データベースでサポートされているいくつかのスキーマ操作がサポートされていません。 サポートされていない操作のいずれかを SQLite データベースに適用しようとすると、NotSupportedException がスローされます。
特定の操作を実行するためにはリビルドが試行されます。 リビルドが可能なのは、EF Core モデルの一部であるデータベース成果物に対してのみです。 データベース成果物がモデルの一部でない場合 (たとえば、移行の中で手動で作成された場合)、NotSupportedException が発生します。
| 操作 | サポート対象? |
|---|---|
| AddCheckConstraint | ✔ (リビルド) |
| AddColumn | ✔ |
| AddForeignKey | ✔ (リビルド) |
| AddPrimaryKey | ✔ (リビルド) |
| AddUniqueConstraint | ✔ (リビルド) |
| AlterColumn | ✔ (リビルド) |
| CreateIndex | ✔ |
| CreateTable | ✔ |
| DropCheckConstraint | ✔ (リビルド) |
| DropColumn | ✔ (リビルド) |
| DropForeignKey | ✔ (リビルド) |
| DropIndex | ✔ |
| DropPrimaryKey | ✔ (リビルド) |
| DropTable | ✔ |
| DropUniqueConstraint | ✔ (リビルド) |
| RenameColumn | ✔ |
| RenameIndex | ✔ (リビルド) |
| RenameTable | ✔ |
| EnsureSchema | ✔ (no-op) |
| DropSchema | ✔ (no-op) |
| Insert | ✔ |
| 更新 | ✔ |
| 削除 | ✔ |
移行に関する制限事項の回避策
リビルドを実行するために移行でコードを手動で記述することによって、これらの制限事項の一部を回避できます。 テーブルのリビルドには、新しいテーブルの作成、新しいテーブルへのデータのコピー、古いテーブルの削除、新しいテーブルの名前変更が必要です。 これらの手順の一部を実行するには、Sql メソッドを使用する必要があります。
詳細については、SQLite のドキュメントで、他の種類のテーブル スキーマ変更を行う方法に関する記事を参照してください。
べき等スクリプトの制限事項
他のデータベースとは異なり、SQLite には手続き型の言語が含まれていません。 このため、べき等移行スクリプトに必要な if then ロジックを生成する方法はありません。
データベースに適用された最後の移行がわかっている場合は、その移行から最新の移行にスクリプトを生成できます。
dotnet ef migrations script CurrentMigration
それ以外の場合は、dotnet ef database update を使用して移行を適用することをお勧めします。 このコマンドを実行するときにデータベース ファイルを指定できます。
dotnet ef database update --connection "Data Source=My.db"
同時移行の保護
EF9 では、移行の実行時にロック メカニズムが導入されました。 これは、データベースが破損状態になる可能性があるため、同時に発生する複数の移行実行から保護することを目的としています。 これは、 Migrate メソッドを使用して実行時に移行を適用することによって生じる潜在的な問題の 1 つです (詳細については、 移行の適用 を参照してください)。 これを軽減するために、EF は移行操作が適用される前に、データベースに排他ロックを作成します。
残念ながら、SQLite には組み込みのロック メカニズムがないため、EF Core によって別のテーブル (__EFMigrationsLock) が作成され、ロックに使用されます。 移行が完了し、シード処理コードの実行が完了すると、ロックが解放されます。 ただし、何らかの理由で復旧不可能な方法で移行が失敗した場合、ロックが正しく解放されない可能性があります。 この場合、連続する移行は SQL の実行をブロックされるため、完了しません。 データベース内の __EFMigrationsLock テーブルを削除することで、手動でブロックを解除できます。
関連項目
.NET