Omezení zprostředkovatele databáze SQLite EF Core
Poskytovatel SQLite má řadu omezení migrace. Většina těchto omezení je výsledkem omezení základního databázového stroje SQLite a nejsou specifická pro EF.
Omezení modelování
Společná relační knihovna (sdílená poskytovateli relačních databází Entity Framework) definuje rozhraní API pro koncepty modelování, které jsou společné pro většinu relačních databázových strojů. Poskytovatel SQLite nepodporuje několik těchto konceptů.
- Schémata
- Sekvence
- Tokeny souběžnosti generované databází (viz dokumentace)
Omezení dotazů
SQLite nativně nepodporuje následující datové typy. EF Core může číst a zapisovat hodnoty těchto typů a dotazování na rovnost (where e.Property == value
) je také podporováno. Jiné operace, jako je například porovnání a řazení, však budou vyžadovat vyhodnocení klienta.
- DateTimeOffset
- Desetinné číslo
- TimeSpan
- UInt64
DateTimeOffset
Místo toho doporučujeme použít hodnoty DateTime. Při zpracování více časových pásem doporučujeme hodnoty před uložením a následnou převodem zpět na příslušné časové pásmo převést na UTC.
Typ Decimal
poskytuje vysokou úroveň přesnosti. Pokud ale tuto úroveň přesnosti nepotřebujete, doporučujeme místo toho použít dvojité. Pomocí převaděče hodnot můžete ve třídách pokračovat v používání desetinných míst.
modelBuilder.Entity<MyEntity>()
.Property(e => e.DecimalProperty)
.HasConversion<double>();
Omezení migrace
Databázový stroj SQLite nepodporuje řadu operací schématu podporovaných většinou jiných relačních databází. Pokud se pokusíte použít jednu z nepodporovaných operací na databázi SQLite, NotSupportedException
vyvolá se vyvolá.
Opětovné sestavení se pokusí provést určité operace. Opětovné sestavení je možné pouze pro artefakty databáze, které jsou součástí modelu EF Core. Pokud artefakt databáze není součástí modelu , například pokud byl vytvořen ručně uvnitř migrace, NotSupportedException
je stále vyvolán.
Operace | Podporováno? |
---|---|
AddCheckConstraint | ✔ (opětovné sestavení) |
AddColumn | ✔ |
AddForeignKey | ✔ (opětovné sestavení) |
AddPrimaryKey | ✔ (opětovné sestavení) |
AddUniqueConstraint | ✔ (opětovné sestavení) |
AlterColumn | ✔ (opětovné sestavení) |
CreateIndex | ✔ |
Vytvořit tabulku | ✔ |
DropCheckConstraint | ✔ (opětovné sestavení) |
DropColumn | ✔ (opětovné sestavení) |
DropForeignKey | ✔ (opětovné sestavení) |
DropIndex | ✔ |
DropPrimaryKey | ✔ (opětovné sestavení) |
DropTable | ✔ |
DropUniqueConstraint | ✔ (opětovné sestavení) |
PřejmenovatSloupce | ✔ |
RenameIndex | ✔ (opětovné sestavení) |
Přejmenovat tabulku | ✔ |
Ujistěte se, žeSchema | ✔ (no-op) |
DropSchema | ✔ (no-op) |
Vložit | ✔ |
Aktualizovat | ✔ |
Odstranění | ✔ |
Alternativní řešení pro omezení migrace
Některá z těchto omezení můžete obejít ručním napsáním kódu v migracích za účelem opětovného sestavení. Opětovné sestavení tabulky zahrnuje vytvoření nové tabulky, kopírování dat do nové tabulky, vyřazení staré tabulky a přejmenování nové tabulky. K provedení některých z těchto kroků budete muset použít Sql(string)
metodu.
Další podrobnosti najdete v tématu Vytváření dalších typů změn schématu tabulky v dokumentaci SQLite.
Omezení idempotentního skriptu
Na rozdíl od jiných databází neobsahuje SQLite procedurální jazyk. Z tohoto důvodu neexistuje způsob, jak vygenerovat logiku if-then vyžadovanou skripty migrace idempotentní.
Pokud znáte poslední migraci použitou na databázi, můžete z této migrace na nejnovější migraci vygenerovat skript.
dotnet ef migrations script CurrentMigration
V opačném případě doporučujeme použít dotnet ef database update
migrace. Při spuštění příkazu můžete zadat soubor databáze.
dotnet ef database update --connection "Data Source=My.db"
Souběžná ochrana migrace
EF9 zavedl mechanismus uzamykání při provádění migrací. Cílem je chránit před několika prováděními migrace současně, protože by databáze mohla opustit poškozený stav. Toto je jeden z potenciálních problémů způsobených použitím migrace za běhu pomocí DbContext.Database.Migrate()
metody (další informace najdete v tématu Použití migrací ). Aby se tento problém zmírnit, ef vytvoří výhradní zámek databáze před provedením jakýchkoli operací migrace.
SQLite bohužel nemá integrovaný mechanismus uzamčení, takže EF vytvoří samostatnou tabulku (__EFMigrationsLock
) a použije ji k uzamčení. Zámek se uvolní po dokončení migrace a počáteční kód dokončí provádění. Pokud ale z nějakého důvodu migrace selže neobnovitelným způsobem, zámek nemusí být uvolněn správně. Pokud k tomu dojde, po sobě jdoucí migrace se zablokují v provádění SQL, a proto se nikdy nedokončí. Odstraněním __EFMigrationsLock
tabulky v databázi je můžete ručně odblokovat.