Bagikan melalui


Batasan Penyedia Database Inti SQLite EF

Penyedia SQLite memiliki sejumlah batasan migrasi. Sebagian besar batasan ini adalah hasil dari keterbatasan dalam mesin database SQLite yang mendasar dan tidak spesifik untuk EF.

Batasan pemodelan

Pustaka relasional umum (dibagikan oleh penyedia database relasional EF Core) mendefinisikan API untuk konsep pemodelan yang umum untuk sebagian besar mesin database relasional. Beberapa konsep ini tidak didukung oleh penyedia SQLite.

Batasan kueri

SQLite tidak secara asli mendukung jenis data berikut. EF Core dapat membaca dan menulis nilai jenis ini, dan kueri untuk kesetaraan (where e.Property == value) juga didukung. Namun, operasi lain, seperti perbandingan dan pemesanan akan memerlukan evaluasi pada klien.

  • DateTimeOffset
  • decimal
  • TimeSpan
  • ulong

Alih-alih DateTimeOffset, sebaiknya gunakan nilai DateTime. Saat menangani beberapa zona waktu, sebaiknya konversi nilai ke UTC sebelum menyimpan lalu mengonversi kembali ke zona waktu yang sesuai.

Jenis ini decimal memberikan tingkat presisi yang tinggi. Namun, jika Anda tidak memerlukan tingkat presisi tersebut, sebaiknya gunakan double sebagai gantinya. Anda dapat menggunakan pengonversi nilai untuk terus menggunakan decimal di kelas Anda.

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

Batasan migrasi

Mesin database SQLite tidak mendukung sejumlah operasi skema yang didukung oleh sebagian besar database relasional lainnya. Jika Anda mencoba menerapkan salah satu operasi yang tidak didukung ke database SQLite, maka NotSupportedException akan dilemparkan.

Pembangunan kembali akan dicoba untuk melakukan operasi tertentu. Pembangunan kembali hanya dimungkinkan untuk artefak database yang merupakan bagian dari model EF Core Anda. Jika artefak database bukan bagian dari model - misalnya, jika dibuat secara manual dalam migrasi - maka akan menghasilkan NotSupportedException.

Operasi Didukung?
TambahkanCheckConstraint ✔ (membangun kembali)
TambahkanColumn
AddForeignKey ✔ (membangun kembali)
AddPrimaryKey ✔ (membangun kembali)
TambahkanUniqueConstraint ✔ (membangun kembali)
AlterColumn ✔ (membangun kembali)
CreateIndex
CreateTable
DropCheckConstraint ✔ (membangun kembali)
DropColumn ✔ (membangun kembali)
DropForeignKey ✔ (membangun kembali)
DropIndex
DropPrimaryKey ✔ (membangun kembali)
DropTable
DropUniqueConstraint ✔ (membangun kembali)
Ganti namaColumn
Ganti namaIndex ✔ (membangun kembali)
Ganti NamaTable
Memastikan Skema ✔ (no-op)
DropSchema ✔ (no-op)
Sisipkan
Pembaruan
Hapus

Solusi batasan migrasi

Anda dapat mengatasi beberapa batasan ini dengan menulis kode secara manual dalam migrasi Anda untuk melakukan pembangunan ulang. Pembangunan ulang tabel melibatkan pembuatan tabel baru, menyalin data ke tabel baru, menghilangkan tabel lama, mengganti nama tabel baru. Anda harus menggunakan Sql metode untuk melakukan beberapa langkah ini.

Lihat Membuat Jenis Perubahan Skema Tabel Lainnya dalam dokumentasi SQLite untuk detail selengkapnya.

Batasan skrip idempogen

Tidak seperti database lain, SQLite tidak menyertakan bahasa prosedural. Karena itu, tidak ada cara untuk menghasilkan logika if-then yang diperlukan oleh skrip migrasi idempogen.

Jika Anda mengetahui migrasi terakhir yang diterapkan ke database, Anda dapat membuat skrip dari migrasi tersebut ke migrasi terbaru.

dotnet ef migrations script CurrentMigration

Jika tidak, sebaiknya gunakan dotnet ef database update untuk menerapkan migrasi. Anda dapat menentukan file database saat menjalankan perintah.

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

Perlindungan migrasi bersamaan

EF9 memperkenalkan mekanisme penguncian saat menjalankan migrasi. Ini bertujuan untuk melindungi dari beberapa eksekusi migrasi yang terjadi secara bersamaan, karena itu dapat meninggalkan database dalam keadaan rusak. Ini adalah salah satu potensi masalah yang dihasilkan dari penerapan migrasi pada runtime menggunakan Migrate metode (lihat Menerapkan migrasi untuk informasi selengkapnya). Untuk mengurangi hal ini, EF membuat kunci eksklusif pada database sebelum operasi migrasi diterapkan.

Sayangnya, SQLite tidak memiliki mekanisme penguncian bawaan, sehingga EF Core membuat tabel terpisah (__EFMigrationsLock) dan menggunakannya untuk penguncian. Kunci dilepaskan ketika migrasi selesai dan kode seeding menyelesaikan eksekusi. Namun, jika karena alasan tertentu migrasi gagal dengan cara yang tidak dapat dipulihkan, kunci mungkin tidak dirilis dengan benar. Jika ini terjadi, migrasi berturut-turut akan diblokir untuk mengeksekusi SQL dan karenanya tidak pernah selesai. Anda dapat membuka blokirnya secara manual dengan menghapus __EFMigrationsLock tabel dalam database.

Lihat juga