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.
- Scheman
- Sekvenser
- Databasgenererade samtidighetstoken (se dokumentationen)
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 DateTimeOffset
rekommenderar 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.