Freigeben über


SQLite EF Core-Datenbank-Anbieter-Einschränkungen

Der SQLite-Anbieter hat eine Reihe von Migrationseinschränkungen. Die meisten dieser Einschränkungen ergeben sich aus Einschränkungen im zugrunde liegenden SQLite-Datenbankmodul und sind nicht spezifisch für EF.

Modellierungseinschränkungen

Die gemeinsame relationale Bibliothek, die von den EF Core relationalen Datenbankanbietern gemeinsam genutzt wird, definiert APIs für Modellierungskonzepte, die den meisten relationalen Datenbankmanagementsystemen gemeinsam sind. Einige dieser Konzepte werden vom SQLite-Anbieter nicht unterstützt.

Abfrageeinschränkungen

SQLite unterstützt die folgenden Datentypen nicht nativ. EF Core kann Werte dieser Typen lesen und schreiben, und die Abfrage nach Gleichheit (where e.Property == value) wird ebenfalls unterstützt. Andere Vorgänge, z. B. Vergleich und Sortierung, erfordern jedoch eine Auswertung auf dem Client.

  • DateTimeOffset
  • decimal
  • TimeSpan
  • ulong

Statt DateTimeOffsetempfehlen wir, DateTime-Werte zu verwenden. Wenn Sie mit mehreren Zeitzonen arbeiten, empfehlen wir Ihnen, die Werte vor dem Speichern in UTC zu konvertieren und dann in die entsprechende Zeitzone zurück zu konvertieren.

Der decimal Typ bietet eine hohe Genauigkeit. Wenn Sie diese Genauigkeit jedoch nicht benötigen, empfehlen wir stattdessen die Verwendung von double. Sie können einen Wertkonverter verwenden, um in Ihren Klassen weiterhin decimal zu verwenden.

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

Migrationseinschränkungen

Das SQLite-Datenbankmodul unterstützt keine Anzahl von Schemavorgängen, die von den meisten anderen relationalen Datenbanken unterstützt werden. Wenn Sie versuchen, einen der nicht unterstützten Vorgänge auf eine SQLite-Datenbank anzuwenden, wird ein NotSupportedException ausgelöst.

Es wird versucht, eine Neuerstellung durchzuführen, um bestimmte Vorgänge auszuführen. Neuerstellungen sind nur für Datenbankartefakte möglich, die Teil Ihres EF Core-Modells sind. Wenn ein Datenbankartefakt nicht Teil des Modells ist , z. B. wenn es manuell innerhalb einer Migration erstellt wurde, wird immer noch ein NotSupportedException ausgelöst.

Vorgang Unterstützt?
AddCheckConstraint ✔ (rebuild)
AddColumn
AddForeignKey ✔ (rebuild)
AddPrimaryKey ✔ (rebuild)
AddUniqueConstraint ✔ (rebuild)
AlterColumn ✔ (rebuild)
CreateIndex
CreateTable
DropCheckConstraint ✔ (rebuild)
DropColumn ✔ (rebuild)
DropForeignKey ✔ (rebuild)
DropIndex
DropPrimaryKey ✔ (rebuild)
DropTable
DropUniqueConstraint ✔ (rebuild)
RenameColumn
RenameIndex ✔ (rebuild)
RenameTable
EnsureSchema ✔ (no-op)
DropSchema ✔ (no-op)
„Insert“
Aktualisieren
Entf

Migrationseinschränkungen Problemumgehung

Sie können einige dieser Einschränkungen umgehen, indem Sie manuell Code in Ihre Migrationen schreiben, um einen Neuaufbau durchzuführen. Um eine Tabelle neu zu erstellen, müssen Sie eine neue Tabelle erstellen, die Daten in die neue Tabelle kopieren, die alte Tabelle löschen und die neue Tabelle umbenennen. Sie müssen die Sql-Methode verwenden, um einige dieser Schritte auszuführen.

Weitere Informationen finden Sie unter Vornehmen anderer Arten von Tabellenschemaänderungen in der SQLite-Dokumentation.

Einschränkungen von Idempotent-Skripts

Im Gegensatz zu anderen Datenbanken enthält SQLite keine prozedurale Sprache. Aus diesem Grund gibt es keine Möglichkeit, die if-then-Logik zu generieren, die von den idempotenten Migrationsskripts benötigt wird.

Wenn Sie wissen, dass die letzte Migration auf eine Datenbank angewendet wurde, können Sie ein Skript aus dieser Migration zur neuesten Migration generieren.

dotnet ef migrations script CurrentMigration

Andernfalls wird empfohlen, dotnet ef database update zum Anwenden von Migrationen zu verwenden. Sie können die Datenbankdatei beim Ausführen des Befehls angeben.

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

Schutz vor gleichzeitigen Migrationen

EF9 hat einen Sperrmechanismus bei der Ausführung von Migrationen eingeführt. Er dient dazu, die gleichzeitige Ausführung mehrerer Migrationen zu verhindern, da dies die Datenbank beschädigen kann. Dies ist eines der potenziellen Probleme, die sich ergeben, wenn Migrationen zur Laufzeit mithilfe der Migrate-Methode angewendet werden. (Weitere Informationen finden Sie unter Anwenden von Migrationen.) Um dies zu vermeiden, erstellt EF eine exklusive Sperre für die Datenbank, bevor Migrationsvorgänge angewendet werden.

Leider verfügt SQLite nicht über einen integrierten Sperrmechanismus, sodass EF Core eine separate Tabelle (__EFMigrationsLock) erstellt und zum Sperren verwendet. Die Sperre wird aufgehoben, wenn die Migration abgeschlossen ist und die Ausführung des Seedingcodes beendet wird. Falls bei der Migration allerdings aus irgendeinem Grund ein nicht behebbarer Fehler auftritt, wird die Sperre möglicherweise nicht ordnungsgemäß aufgehoben. In diesem Fall werden nachfolgende Migrationen an der Ausführung von SQL-Code gehindert und können somit nicht abgeschlossen werden. Sie können die Blockierung manuell aufheben, indem Sie die Tabelle __EFMigrationsLock in der Datenbank löschen.

Siehe auch