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 (współdzielona przez dostawców relacyjnych baz danych platformy Entity Framework) definiuje interfejsy API do modelowania pojęć, które są wspólne dla większości aparató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
  • Dziesiętne
  • przedział_czasu
  • UInt64

DateTimeOffsetZamiast polecenia zalecamy 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 podwójnej wartości. Możesz użyć konwertera wartości, aby nadal używać liczby dziesiętnej w 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 on nadal zgłaszany.

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(string) 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 DbContext.Database.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 ef 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ż