Dela via


Begränsningar för SQLite EF Core-databasprovider

SQLite-providern har ett antal migreringsbegränsningar. De flesta av dessa begränsningar är ett resultat av begränsningar i den underliggande SQLite-databasmotorn och är inte specifika för EF.

Modelleringsbegränsningar

Det gemensamma relationsbiblioteket (som delas av EF Core-relationsdatabasprovidrar) definierar API:er för modellering av begrepp som är gemensamma för de flesta relationsdatabasmotorer. Ett par av dessa begrepp stöds inte av SQLite-providern.

Frågebegränsningar

SQLite stöder inte följande datatyper internt. EF Core kan läsa och skriva värden för dessa typer, och frågor om likhet (where e.Property == value) stöds också. Andra operationer, som jämförelse och sortering, kräver dock utvärdering på klienten.

  • DateTimeOffset
  • decimal
  • TimeSpan
  • ulong

I stället för DateTimeOffsetrekommenderar vi att du använder DateTime värden. När du hanterar flera tidszoner rekommenderar vi att du konverterar värdena till UTC innan du sparar och sedan konverterar tillbaka till rätt tidszon.

Den decimal typen ger hög precision. Om du inte behöver den precisionsnivån rekommenderar vi dock att du använder double i stället. Du kan använda en värdekonverterare för att fortsätta använda decimal i dina klasser.

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

Begränsningar för migrering

SQLite-databasmotorn stöder inte ett antal schemaåtgärder som stöds av de flesta andra relationsdatabaser. Om du försöker tillämpa en av de åtgärder som inte stöds på en SQLite-databas genereras en NotSupportedException.

En ombyggnad görs för att utföra vissa åtgärder. Återskapanden är endast möjliga för databasartefakter som ingår i DIN EF Core-modell. Om en databasartefakt inte är en del av modellen – till exempel om den skapades manuellt i en migrering – genereras fortfarande en NotSupportedException.

Operation Stödd?
LäggTillKontrollbegränsning ✔ (återskapa)
AddColumn
Lägg till främmande nyckel ✔ (återskapa)
LäggTillPrimärnyckel ✔ (återskapa)
Lägg till unik begränsning ✔ (återskapa)
AlterColumn ✔ (återskapa)
Skapa Index
SkapaTabell
Ta bort kontrollbegränsning ✔ (återskapa)
TaBortKolumn ✔ (återskapa)
DropForeignKey ✔ (återskapa)
DropIndex
DropPrimaryKey ✔ (återskapa)
DropTable
Ta bort unik begränsning ✔ (återskapa)
BytNamnPåKolumn
BytNamnPåIndex ✔ (återskapa)
BytNamnPåTabell
EnsureSchema ✔ (no-op)
DropSchema ✔ (no-op)
Infoga
Uppdatera
Ta bort

Lösning på migreringsbegränsningar

Du kan lösa vissa av dessa begränsningar genom att manuellt skriva kod i dina migreringar för att utföra en återuppbyggnad. Om du återskapar tabellen måste du skapa en ny tabell, kopiera data till den nya tabellen, släppa den gamla tabellen och byta namn på den nya tabellen. Du måste använda metoden Sql för att utföra några av de här stegen.

Mer information finns i Att göra andra typer av tabellschemaändringar i SQLite-dokumentationen.

Begränsningar för Idempotent-skript

Till skillnad från andra databaser innehåller SQLite inte något procedurspråk. På grund av detta finns det inget sätt att generera den if-then-logik som krävs av idempotent-migreringsskripten.

Om du vet att den senaste migreringen tillämpades på en databas kan du generera ett skript från migreringen till den senaste migreringen.

dotnet ef migrations script CurrentMigration

Annars rekommenderar vi att du använder dotnet ef database update för att tillämpa migreringar. Du kan ange databasfilen när du kör kommandot.

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

Skydd mot samtidiga migreringar

EF9 introducerade en låsningsmekanism när migreringar körs. Syftet är att skydda mot flera migreringskörningar samtidigt, eftersom det kan lämna databasen i ett skadat tillstånd. Detta är ett av de potentiella problem som kan uppstå när migreringar tillämpas vid körning med hjälp av Migrate-metoden (mer information finns i Tillämpa migreringar). För att minimera detta skapar EF ett exklusivt lås på databasen innan några migreringsåtgärder tillämpas.

SQLite har tyvärr ingen inbyggd låsmekanism, så EF Core skapar en separat tabell (__EFMigrationsLock) och använder den för låsning. Låset frigörs när migreringen är klar och seeding-koden slutför körningen. Men om migreringen av någon anledning misslyckas på ett icke-återställningsbart sätt kanske låset inte släpps korrekt. Om detta händer blockeras efterföljande migreringar från att köra SQL och slutförs därför aldrig. Du kan avblockera dem manuellt genom att ta bort tabellen __EFMigrationsLock i databasen.

Se även