Udostępnij za pośrednictwem


Ograniczenia dostawcy bazy danych SQLite EF Core

Dostawca SQLite ma szereg ograniczeń migracji. Większość tych ograniczeń wynika z ograniczeń w bazowym aucie bazy danych SQLite i nie jest specyficzna dla programu EF.

Ograniczenia modelowania

Wspólna biblioteka relacyjna (wykorzystywana przez dostawców relacyjnych baz danych platformy EF Core) definiuje interfejsy API do modelowania pojęć, które są wspólne dla większości silników relacyjnych baz danych. Kilka z tych pojęć nie jest obsługiwanych przez dostawcę SQLite.

Ograniczenia zapytań

SqLite nie obsługuje natywnie następujących typów danych. Program EF Core może odczytywać i zapisywać wartości tych typów, a wykonywanie zapytań o równość (where e.Property == value) jest również obsługiwane. Inne operacje, takie jak porównanie i kolejność, będą wymagały oceny na kliencie.

  • DateTimeOffset
  • decimal
  • TimeSpan
  • ulong

Zamiast DateTimeOffsetzalecamy używanie wartości DateTime. Podczas obsługi wielu stref czasowych zalecamy przekonwertowanie wartości na utc przed zapisaniem, a następnie przekonwertowanie z powrotem na odpowiednią strefę czasową.

Typ decimal zapewnia wysoki poziom dokładności. Jeśli jednak nie potrzebujesz tego poziomu dokładności, zalecamy użycie double zamiast tego. Możesz użyć konwertera wartości typu, aby nadal używać decimal w swoich klasach.

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

Ograniczenia migracji

Aparat bazy danych SQLite nie obsługuje wielu operacji schematu obsługiwanych przez większość innych relacyjnych baz danych. Jeśli spróbujesz zastosować jedną z nieobsługiwanych operacji do bazy danych SQLite, zostanie zgłoszony element NotSupportedException .

Ponowna kompilacja zostanie podjęta w celu wykonania pewnych operacji. Ponowne kompilacje są możliwe tylko w przypadku artefaktów bazy danych, które są częścią modelu EF Core. Jeśli artefakt bazy danych nie jest częścią modelu — na przykład, jeśli został utworzony ręcznie wewnątrz migracji — NotSupportedException jest nadal wyrzucany.

Operacja Obsługiwane?
AddCheckConstraint ✔ (ponowne kompilowanie)
AddColumn
AddForeignKey ✔ (ponowne kompilowanie)
AddPrimaryKey ✔ (ponowne kompilowanie)
AddUniqueConstraint ✔ (ponowne kompilowanie)
AlterColumn ✔ (ponowne kompilowanie)
CreateIndex
CreateTable
DropCheckConstraint ✔ (ponowne kompilowanie)
DropColumn ✔ (ponowne kompilowanie)
DropForeignKey ✔ (ponowne kompilowanie)
DropIndex
DropPrimaryKey ✔ (ponowne kompilowanie)
DropTable
DropUniqueConstraint ✔ (ponowne kompilowanie)
Zmień nazwękolumny
Zmień nazwę indeksu ✔ (ponowne kompilowanie)
Zmień nazwę tabeli
Upewnij się, ŻeSchema ✔ (no-op)
DropSchema ✔ (no-op)
Insert
Zaktualizuj
Delete

Obejście ograniczeń migracji

Niektóre z tych ograniczeń można obejść, ręcznie pisząc kod w migracjach, aby przeprowadzić ponowną kompilację. Ponowne kompilowanie tabeli obejmuje utworzenie nowej tabeli, skopiowanie danych do nowej tabeli, usunięcie starej tabeli, zmiana nazwy nowej tabeli. Aby wykonać niektóre z tych kroków, należy użyć Sql metody .

Aby uzyskać więcej informacji, zobacz Artykuł Making Other Kinds Of Table Schema Changes in the SQLite documentation (Wprowadzanie innych rodzajów zmian schematu tabeli w dokumentacji SQLite).

Ograniczenia skryptu idempotentnego

W przeciwieństwie do innych baz danych SQLite nie zawiera języka proceduralnego. W związku z tym nie ma możliwości wygenerowania logiki if-then wymaganej przez skrypty migracji idempotentnej.

Jeśli znasz ostatnią migrację zastosowaną do bazy danych, możesz wygenerować skrypt z tej migracji do najnowszej migracji.

dotnet ef migrations script CurrentMigration

W przeciwnym razie zalecamy użycie polecenia dotnet ef database update w celu zastosowania migracji. Podczas uruchamiania polecenia można określić plik bazy danych.

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

Ochrona równoczesnych migracji

Program EF9 wprowadził mechanizm blokowania podczas wykonywania migracji. Ma ona na celu ochronę przed równoczesnym wykonywaniem wielu wykonań migracji, ponieważ może to spowodować pozostawienie bazy danych w stanie uszkodzonym. Jest to jeden z potencjalnych problemów wynikających z stosowania migracji w czasie wykonywania przy użyciu Migrate metody (zobacz Stosowanie migracji , aby uzyskać więcej informacji). Aby temu zapobiec, program EF tworzy wyłączną blokadę bazy danych przed zastosowaniem jakichkolwiek operacji migracji.

Niestety sqLite nie ma wbudowanego mechanizmu blokowania, więc program EF Core tworzy oddzielną tabelę (__EFMigrationsLock) i używa jej do blokowania. Blokada jest zwalniana po zakończeniu migracji, a kod inicjujący zakończy wykonywanie. Jeśli jednak z jakiegoś powodu migracja nie powiedzie się w sposób niemożliwy do odzyskania, blokada może nie zostać poprawnie zwolniona. W takim przypadku kolejne migracje zostaną zablokowane podczas wykonywania programu SQL i w związku z tym nigdy nie zostaną ukończone. Możesz je ręcznie odblokować, usuwając tabelę __EFMigrationsLock w bazie danych.

Zobacz też