Breaking Changes in EF Core 7.0 (EF7)
Auf dieser Seite werden API-Änderungen und Behavior Changes dokumentiert, die bei einem Update von EF Core 6 auf EF Core 7 zu Problemen mit bestehenden Anwendungen führen können. Überprüfen Sie frühere grundlegende Änderungen, wenn sie von einer früheren Version von EF Core aktualisiert werden:
Zielframework
EF Core 7.0 zielt auf .NET 6 ab. Dies bedeutet, dass vorhandene Anwendungen, die auf .NET 6 abzielen, dies weiterhin tun können. Anwendungen für ältere .NET-, .NET Core- und .NET Framework-Versionen müssen .NET 6 oder .NET 7 für die Verwendung von EF Core 7.0 verwenden.
Zusammenfassung
Änderungen mit hoher Auswirkung
Encrypt
geht standardmäßig auf true
für SQL Server-Verbindungen zurück
Tracking-Problem: SqlClient #1210
Wichtig
Dies ist eine schwerwiegende Breaking Change im Microsoft.Data.SqlClient-Paket. Es gibt nichts, was in EF Core getan werden kann, um diese Änderung wiederherzustellen oder zu mindern. Bitte senden Sie Ihr Feedback an das GitHub-Repository „Microsoft.Data.SqlClient“, oder wenden Sie sich an einen Microsoft-Supportmitarbeiter, um Antworten auf Ihre Fragen oder Hilfe zu erhalten.
Altes Verhalten
SqlClient-Verbindungszeichenfolgen verwenden standardmäßig Encrypt=False
. Dies ermöglicht Verbindungen auf Entwicklungscomputern, auf denen der lokale Server kein gültiges Zertifikat besitzt.
Neues Verhalten
SqlClient-Verbindungszeichenfolgen verwenden standardmäßig Encrypt=True
. Dies bedeutet Folgendes:
- Der Server muss mit seinem Zertifikat konfiguriert werden
- Der Client muss diesem Zertifikat vertrauen
Wenn diese Bedingungen nicht erfüllt sind, wird ein SqlException
-Fehler ausgelöst. Beispiel:
Eine Verbindung mit dem Server wurde erfolgreich hergestellt, aber dann trat während des Anmeldevorgangs ein Fehler auf. (Anbieter: SSL-Anbieter, Fehler: 0 – Die Zertifikatkette wurde von einer Zertifizierungsstelle ausgestellt, die nicht vertrauenswürdig ist.)
Warum?
Diese Änderung wurde vorgenommen, um sicherzustellen, dass entweder die Verbindung sicher ist oder die Anwendung keine Verbindung herstellen kann.
Gegenmaßnahmen
Es gibt drei Möglichkeiten fortzufahren:
- Installieren Sie ein gültiges Zertifikat auf dem Server. Beachten Sie, dass dies ein beteiligter Prozess ist und ein Zertifikat erhält und sicherstellt, dass es von einer vom Client vertrauenswürdigen Zertifizierungsstelle signiert wird.
- Wenn der Server über ein Zertifikat verfügt, dieses vom Client aber nicht als vertrauenswürdig eingestuft wird, legen Sie Folgendes fest, um die Umgehung des normalen Vertrauensmechanismus zu ermöglichen:
TrustServerCertificate=True
. - Fügen Sie der Verbindungszeichenfolge explizit
Encrypt=False
hinzu.
Warnung
Optionen 2 und 3 lassen den Server in einem potenziell unsicheren Zustand.
Einige Warnungen lösen ausnahmen standardmäßig erneut aus
Nachverfolgung von Issue 29069
Altes Verhalten
In EF Core 6.0 bedeutete ein Fehler im SQL Server-Anbieter, dass einige Warnungen, die zum Auslösen von Ausnahmen konfiguriert sind, stattdessen protokolliert wurden, aber keine Ausnahmen auslösen. Diese Warnungen sind:
EventId | Beschreibung |
---|---|
RelationalEventId.AmbientTransactionWarning | Eine Anwendung hat möglicherweise erwartet, dass eine Umgebungstransaktion verwendet wird, wenn sie tatsächlich ignoriert wurde. |
RelationalEventId.IndexPropertiesBothMappedAndNotMappedToTable | Ein Index spezifiziert Eigenschaften, von denen einige einer Spalte in einer Tabelle zugeordnet sind und einige nicht. |
RelationalEventId.IndexPropertiesMappedToNonOverlappingTables | Ein Index gibt Eigenschaften an, die sich auf Spalten in nicht überlappenden Tabellen beziehen. |
RelationalEventId.ForeignKeyPropertiesMappedToUnrelatedTables | Ein Fremdschlüssel gibt Eigenschaften an, die sich nicht auf die Bezugstabellen beziehen. |
Neues Verhalten
Ab EF Core 7.0 führen diese Warnungen standardmäßig wieder zu einer Ausnahme.
Warum?
Dies sind Probleme, die sehr wahrscheinlich auf einen Fehler im Anwendungscode hinweisen, der behoben werden sollte.
Gegenmaßnahmen
Beheben Sie das zugrunde liegende Problem, das der Grund für die Warnung ist.
Alternativ kann die Warnstufe so geändert werden, dass sie nur protokolliert oder vollständig unterdrückt wird. Beispiel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Ignore(RelationalEventId.AmbientTransactionWarning));
SQL Server-Tabellen mit Triggern oder bestimmten berechneten Spalten erfordern jetzt eine spezielle EF Core-Konfiguration
Nachverfolgung von Issue 27372
Altes Verhalten
In früheren Versionen des SQL Server-Anbieters wurden Änderungen über eine weniger effiziente Technik gespeichert, die immer funktionierte.
Neues Verhalten
Standardmäßig speichert EF Core jetzt Änderungen über eine wesentlich effizientere Technik; leider wird diese Technik auf SQL Server nicht unterstützt, wenn die Zieltabelle Datenbank-Trigger oder bestimmte Arten von berechneten Spalten hat. Weitere Informationen finden Sie in der SQL Server-Dokumentation.
Warum?
Die mit der neuen Methode verbundenen Leistungsverbesserungen sind so bedeutend, dass es wichtig ist, sie den Benutzern standardmäßig zur Verfügung zu stellen. Gleichzeitig schätzen wir die Verwendung von Datenbanktriggern oder der betroffenen berechneten Spalten in EF Core-Anwendungen als so gering ein, dass die negativen Auswirkungen der Änderungen durch den Leistungsgewinn aufgewogen werden.
Gegenmaßnahmen
Ab EF Core 8.0 kann explizit konfiguriert werden, ob die „OUTPUT“-Klausel verwendet wird oder nicht. Zum Beispiel:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.UseSqlOutputClause(false));
}
In EF7 oder höher: Wenn die Zieltabelle einen Auslöser hat, können Sie EF Core dies mitteilen, und EF greift dann auf die vorherige, weniger effiziente Technik zurück. Dazu muss der entsprechende Entitätstyp wie folgt konfiguriert werden:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.HasTrigger("SomeTrigger"));
}
Beachten Sie, dass dadurch EF Core den Trigger nicht wirklich erstellt oder verwaltet – es informiert EF Core derzeit nur, dass Trigger in der Tabelle vorhanden sind. Infolgedessen kann jeder Auslösername verwendet werden. Die Angabe eines Auslösers kann verwendet werden, um das alte Verhalten wiederherzustellen, auch wenn kein Auslöser in der Tabelle vorhanden ist.
Wenn die meisten oder alle Ihre Tabellen über Trigger verfügen, können Sie auf die Verwendung der neueren, effizienten Technik für alle Tabellen Ihres Modells verzichten, indem Sie die folgende Modellbaukonvention verwenden:
public class BlankTriggerAddingConvention : IModelFinalizingConvention
{
public virtual void ProcessModelFinalizing(
IConventionModelBuilder modelBuilder,
IConventionContext<IConventionModelBuilder> context)
{
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
{
var table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
if (table != null
&& entityType.GetDeclaredTriggers().All(t => t.GetDatabaseName(table.Value) == null)
&& (entityType.BaseType == null
|| entityType.GetMappingStrategy() != RelationalAnnotationNames.TphMappingStrategy))
{
entityType.Builder.HasTrigger(table.Value.Name + "_Trigger");
}
foreach (var fragment in entityType.GetMappingFragments(StoreObjectType.Table))
{
if (entityType.GetDeclaredTriggers().All(t => t.GetDatabaseName(fragment.StoreObject) == null))
{
entityType.Builder.HasTrigger(fragment.StoreObject.Name + "_Trigger");
}
}
}
}
}
Verwenden Sie die Konvention für Ihr DbContext
, indem Sie ConfigureConventions
außer Kraft setzen:
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Conventions.Add(_ => new BlankTriggerAddingConvention());
}
Dadurch wird HasTrigger
für alle Tabellen Ihres Modells aufgerufen, so dass Sie dies nicht für jede einzelne Tabelle manuell tun müssen.
SQLite-Tabellen mit AFTER-Triggern und virtuellen Tabellen erfordern jetzt eine spezielle EF Core-Konfiguration
Nachverfolgung von Issue 29916
Altes Verhalten
In früheren Versionen des SQLite-Anbieters wurden Änderungen über eine weniger effiziente Technik gespeichert, die immer funktionierte.
Neues Verhalten
Standardmäßig speichert EF Core Änderungen mithilfe der RETURNING-Klausel jetzt mithilfe einer effizienteren Technik. Leider wird diese Technik für SQLite nicht unterstützt, wenn die Zieltabelle über Datenbank-AFTER-Trigger verfügt, virtuell ist oder ältere Versionen von SQLite verwendet werden. Weitere Details finden Sie in der Dokumentation zu SQLite.
Warum?
Die mit der neuen Methode verbundenen Vereinfachungen und Leistungsverbesserungen sind so bedeutend, dass es wichtig ist, sie den Benutzern standardmäßig zur Verfügung zu stellen. Gleichzeitig schätzen wir die Verwendung von Datenbanktriggern und virtuellen Tabellen in EF Core-Anwendungen als so gering ein, dass die negativen Auswirkungen der Änderungen durch den Leistungsgewinn aufgewogen werden.
Gegenmaßnahmen
In EF Core 8.0 wurde die UseSqlReturningClause
-Methode eingeführt, um explizit auf das ältere, weniger effiziente SQL zurückzugreifen. Zum Beispiel:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.UseSqlReturningClause(false));
}
Wenn Sie noch EF Core 7.0 verwenden, können Sie den alten Mechanismus für die gesamte Anwendung wiederherstellen, indem Sie den folgenden Code in Ihre Kontextkonfiguration einfügen:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlite(...)
.ReplaceService<IUpdateSqlGenerator, SqliteLegacyUpdateSqlGenerator>();
Änderungen mit mittlerer Auswirkung
Verwaiste Nachfolger optionaler Beziehungen werden nicht automatisch gelöscht
Nachverfolgung von Issue 27217
Altes Verhalten
Eine Beziehung ist optional, wenn der Fremdschlüssel Nullwerte zulässt. Durch Festlegen des Fremdschlüssels auf NULL kann die abhängige Entität ohne zugehörige Prinzipalentität vorhanden sein. Optionale Beziehungen können für die Verwendung von Löschweitergaben konfiguriert werden, obwohl dies nicht die Standardeinstellung ist.
Eine optionale abhängige Datei kann von ihrer Hauptdatei abgetrennt werden, indem entweder ihr Fremdschlüssel auf NULL gesetzt oder die Navigation zu oder von ihr gelöscht wird. In EF Core 6.0 würde dies dazu führen, dass die abhängige Nachricht gelöscht wird, wenn die Beziehung für die Löschweitergabe konfiguriert wurde.
Neues Verhalten
Ab EF Core 7.0 wird der abhängige Benutzer nicht mehr gelöscht. Beachten Sie, dass beim Löschen des Prinzipals auch die abhängigen Daten gelöscht werden, da für die Beziehung eine Löschweitergabe konfiguriert ist.
Warum?
Die abhängige Entität kann auch ohne Beziehung zu einem Prinzipal existieren, so dass eine Trennung der Beziehung nicht zur Löschung der Entität führen sollte.
Gegenmaßnahmen
Die abhängigen Elemente können explizit gelöscht werden:
context.Remove(blog);
Oder SaveChanges
kann außer Kraft gesetzt oder abgefangen werden, um abhängige Personen ohne prinzipiellen Bezug zu löschen. Beispiel:
context.SavingChanges += (c, _) =>
{
foreach (var entry in ((DbContext)c!).ChangeTracker
.Entries<Blog>()
.Where(e => e.State == EntityState.Modified))
{
if (entry.Reference(e => e.Author).CurrentValue == null)
{
entry.State = EntityState.Deleted;
}
}
};
Die Löschweitergabe wird zwischen Tabellen konfiguriert, wenn die TPT-Zuordnung mit SQL Server verwendet wird
Nachverfolgung von Issue 28532
Altes Verhalten
Beim Zuordnen einer Vererbungshierarchie mithilfe der TPT-Strategie muss die Basistabelle unabhängig vom tatsächlichen Typ dieser Entität eine Zeile für jede gespeicherte Entität enthalten. Beim Löschen der Zeile in der Basistabelle sollten Zeilen in allen anderen Tabellen gelöscht werden. EF Core konfiguriert dafür eine Löschweitergabe.
In EF Core 6.0 bedeutete ein Fehler im SQL Server-Datenbankanbieter, dass diese Löschweitergaben nicht erstellt wurden.
Neues Verhalten
Ab EF Core 7.0 werden die Löschweitergaben jetzt für SQL Server genauso wie für andere Datenbanken erstellt.
Warum?
Durch Löschweitergabe aus der Basistabelle an die Untertabellen in TPT kann eine Entität gelöscht werden, indem sie die Zeile in der Basistabelle löscht.
Gegenmaßnahmen
In den meisten Fällen sollte diese Änderung keine Probleme verursachen. SQL Server ist jedoch sehr restriktiv, wenn zwischen Tabellen mehrere kaskadierende Verhaltensweisen konfiguriert sind. Dies bedeutet, dass SQL Server möglicherweise den folgenden Fehler generiert, wenn eine kaskadierende Beziehung zwischen Tabellen in der TPT-Zuordnung vorhanden ist:
Microsoft.Data.SqlClient.SqlException: Die LÖSCHEN-Anweisung ist mit der REFERENZ-Einschränkung „FK_Blogs_People_OwnerId“ in Konflikt geraten. Der Konflikt ist in der Spalte „OwnerId“ der Tabelle „dbo.Blogs“ in der Datenbank „Scratch“ aufgetreten. Die Anweisung wurde beendet.
Mit diesem Modell wird beispielsweise ein Zyklus von kaskadierenden Beziehungen erstellt:
[Table("FeaturedPosts")]
public class FeaturedPost : Post
{
public int ReferencePostId { get; set; }
public Post ReferencePost { get; set; } = null!;
}
[Table("Posts")]
public class Post
{
public int Id { get; set; }
public string? Title { get; set; }
public string? Content { get; set; }
}
Einer dieser Elemente muss so konfiguriert werden, dass keine Löschweitergaben auf dem Server verwendet werden. So ändern Sie beispielsweise die explizite Beziehung:
modelBuilder
.Entity<FeaturedPost>()
.HasOne(e => e.ReferencePost)
.WithMany()
.OnDelete(DeleteBehavior.ClientCascade);
Oder um die implizite Beziehung zu ändern, die für die TPT-Zuordnung erstellt wurde:
modelBuilder
.Entity<FeaturedPost>()
.HasOne<Post>()
.WithOne()
.HasForeignKey<FeaturedPost>(e => e.Id)
.OnDelete(DeleteBehavior.ClientCascade);
Höhere Wahrscheinlichkeit der Fehler „ausgelastet/gesperrt“ in SQLite, wenn keine Write-Ahead-Protokollierung verwendet wird
Altes Verhalten
In früheren Versionen des SQLite-Anbietenden wurden Änderungen mithilfe einer weniger effizienten Technik gespeichert, die automatisch wiederholen konnte, wenn die Tabelle gesperrt/ausgelastet und die Write-Ahead-Protokollierung nicht aktiviert war.
Neues Verhalten
Standardmäßig speichert EF Core Änderungen mithilfe der RETURNING-Klausel jetzt mithilfe einer effizienteren Technik. Leider kann diese Technik nicht automatisch wiederholen, wenn der Status „ausgelastet/gesperrt“ lautet. In einer Multithreadanwendung (z. B. einer Web-App), die keine Write-Ahead-Protokollierung verwendet, treten diese Fehler häufig auf.
Warum?
Die mit der neuen Methode verbundenen Vereinfachungen und Leistungsverbesserungen sind so bedeutend, dass es wichtig ist, sie den Benutzern standardmäßig zur Verfügung zu stellen. Datenbanken, die von EF Core erstellt wurden, aktivieren standardmäßig auch die Write-Ahead-Protokollierung. Das SQLite-Team empfiehlt außerdem, die Write-Ahead-Protokollierung standardmäßig zu aktivieren.
Gegenmaßnahmen
Wenn möglich, sollten Sie die Write-Ahead-Protokollierung für Ihre Datenbank aktivieren. Wenn Ihre Datenbank von EF erstellt wurde, sollte dies bereits der Fall sein. Wenn nicht, können Sie die Write-Ahead-Protokollierung aktivieren, indem Sie den folgenden Befehl ausführen.
PRAGMA journal_mode = 'wal';
Wenn Sie die Write-Ahead-Protokollierung aus irgendeinem Grund nicht aktivieren können, können Sie den alten Mechanismus für die gesamte Anwendung wiederherstellen, indem Sie den folgenden Code in Ihre Kontextkonfiguration einfügen:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlite(...)
.ReplaceService<IUpdateSqlGenerator, SqliteLegacyUpdateSqlGenerator>();
Änderungen mit geringer Auswirkung
Wichtige Eigenschaften müssen möglicherweise mit einem Anbieterwertevergleich konfiguriert werden
Nachverfolgung von Issue 27738
Altes Verhalten
In EF Core 6.0 wurden Schlüsselwerte, die direkt aus den Eigenschaften von Entitätstypen entnommen wurden, zum Vergleich von Schlüsselwerten beim Speichern von Änderungen verwendet. Dadurch werden alle benutzerdefinierten Wertvergleiche verwendet, die für diese Eigenschaften konfiguriert sind.
Neues Verhalten
Ab EF Core 7.0 werden Datenbankwerte für diese Vergleiche verwendet. In den allermeisten Fällen funktioniert das einfach. Wenn jedoch für die Eigenschaften ein benutzerdefinierter Wertevergleich verwendet wurde und dieser Wertevergleich nicht auf die Datenbankwerte angewendet werden kann, kann ein „Anbieterwertevergleich“ erforderlich sein, wie unten dargestellt.
Warum?
Verschiedene Entitätsaufteilungen und Tabellenaufteilung können zu mehreren Eigenschaften führen, die derselben Datenbankspalte zugeordnet sind, und umgekehrt. Dies erfordert, dass Werte nach der Konvertierung in einen Wert verglichen werden, der in der Datenbank verwendet wird.
Gegenmaßnahmen
Konfigurieren Sie einen Anbieterwertvergleich. Betrachten Sie beispielsweise den Fall, in dem ein Wertobjekt als Schlüssel verwendet wird, und der Wertevergleich für diesen Schlüssel Zeichenfolgenvergleiche mit Groß-/Kleinschreibung verwendet:
var blogKeyComparer = new ValueComparer<BlogKey>(
(l, r) => string.Equals(l.Id, r.Id, StringComparison.OrdinalIgnoreCase),
v => v.Id.ToUpper().GetHashCode(),
v => v);
var blogKeyConverter = new ValueConverter<BlogKey, string>(
v => v.Id,
v => new BlogKey(v));
modelBuilder.Entity<Blog>()
.Property(e => e.Id).HasConversion(
blogKeyConverter, blogKeyComparer);
Die Datenbankwerte (Zeichenfolgen) können den für BlogKey
-Typen definierten Wertevergleich nicht direkt verwenden. Daher muss ein Anbieterwertevergleich für Zeichenfolgenvergleiche zwischen Groß- und Kleinschreibung konfiguriert werden:
var caseInsensitiveComparer = new ValueComparer<string>(
(l, r) => string.Equals(l, r, StringComparison.OrdinalIgnoreCase),
v => v.ToUpper().GetHashCode(),
v => v);
var blogKeyComparer = new ValueComparer<BlogKey>(
(l, r) => string.Equals(l.Id, r.Id, StringComparison.OrdinalIgnoreCase),
v => v.Id.ToUpper().GetHashCode(),
v => v);
var blogKeyConverter = new ValueConverter<BlogKey, string>(
v => v.Id,
v => new BlogKey(v));
modelBuilder.Entity<Blog>()
.Property(e => e.Id).HasConversion(
blogKeyConverter, blogKeyComparer, caseInsensitiveComparer);
CHECK-Einschränkungen und andere Tabellenfacetten werden jetzt für die Tabelle konfiguriert
Nachverfolgung von Issue 28205
Altes Verhalten
In EF Core 6.0 wurden HasCheckConstraint
, HasComment
und IsMemoryOptimized
direkt für den Entitätstyp-Generator aufgerufen. Beispiel:
modelBuilder
.Entity<Blog>()
.HasCheckConstraint("CK_Blog_TooFewBits", "Id > 1023");
modelBuilder
.Entity<Blog>()
.HasComment("It's my table, and I'll delete it if I want to.");
modelBuilder
.Entity<Blog>()
.IsMemoryOptimized();
Neues Verhalten
Ab EF Core 7.0 werden diese Methoden stattdessen für den Tabellen-Generator aufgerufen:
modelBuilder
.Entity<Blog>()
.ToTable(b => b.HasCheckConstraint("CK_Blog_TooFewBits", "Id > 1023"));
modelBuilder
.Entity<Blog>()
.ToTable(b => b.HasComment("It's my table, and I'll delete it if I want to."));
modelBuilder
.Entity<Blog>()
.ToTable(b => b.IsMemoryOptimized());
Die vorhandenen Methoden wurden als Obsolete
gekennzeichnet. Sie haben derzeit das gleiche Verhalten wie die neuen Methoden, werden aber in einer zukünftigen Version entfernt.
Warum?
Diese Facetten gelten nur für Tabellen. Sie werden nicht auf zugeordnete Ansichten, Funktionen oder gespeicherte Prozeduren angewendet.
Gegenmaßnahmen
Verwenden Sie die Methoden des Tabellengenerators, wie oben gezeigt.
Die Navigation von neuen Entitäten zu gelöschten Entitäten ist nicht in Ordnung
Nachverfolgung von Issue 28249
Altes Verhalten
Wenn in EF Core 6.0 eine neue Entität entweder über eine Nachverfolgungsabfrage oder durch Anhängen an DbContext
nachverfolgt wird, dann werden Navigationen zu und von verwandten Entitäten im Deleted
-Zustand eingerichtet.
Neues Verhalten
Ab EF Core 7.0 sind Navigationen zu und von Deleted
-Entitäten nicht behoben.
Warum?
Sobald eine Entität als Deleted
markiert ist, macht es selten Sinn, sie mit nicht gelöschten Entitäten zu verknüpfen.
Gegenmaßnahmen
Sie können Entitäten abfragen oder anhängen, bevor Sie sie als Deleted
markieren, oder manuell Navigationseigenschaften zu und von der gelöschten Entität festlegen.
Die Verwendung von FromSqlRaw
und verwandter Methoden des falschen Anbieters löst use-the-correct-method aus
Nachverfolgung von Issue 26502
Altes Verhalten
In EF Core 6.0 kann die Verwendung der Azure Cosmos DB-Erweiterungsmethode FromSqlRaw bei Verwendung eines relationalen Anbieters oder der relationalen Erweiterungsmethode FromSqlRaw bei Verwendung des Azure Cosmos DB-Anbieters im Hintergrund fehlschlagen. Ebenso ist die Verwendung relationaler Methoden für den In-Memory-Anbieter eine automatische Nulloperation.
Neues Verhalten
Ab EF Core 7.0 wird bei Verwendung einer Erweiterungsmethode, die für einen Anbieter entwickelt wurde, bei einem anderen Anbieter eine Ausnahme ausgelöst.
Warum?
Die richtige Erweiterungsmethode muss verwendet werden, damit sie in allen Situationen ordnungsgemäß funktioniert.
Gegenmaßnahmen
Verwenden Sie die richtige Erweiterungsmethode für den verwendeten Anbieter. Wenn auf mehrere Anbieter verwiesen wird, rufen Sie die Erweiterungsmethode als statische Methode auf. Beispiel:
var result = CosmosQueryableExtensions.FromSqlRaw(context.Blogs, "SELECT ...").ToList();
Oder:
var result = RelationalQueryableExtensions.FromSqlRaw(context.Blogs, "SELECT ...").ToList();
Gerüstetes OnConfiguring
ruft IsConfigured
nicht mehr ab
Altes Verhalten
In EF Core 6.0 enthielt der Typ DbContext
, der aus einer bestehenden Datenbank gerüstet wurde, einen Aufruf an IsConfigured
. Beispiel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
optionsBuilder.UseNpgsql("MySecretConnectionString");
}
}
Neues Verhalten
Ab EF Core 7.0 ist der Aufruf an IsConfigured
nicht mehr enthalten.
Warum?
Es gibt sehr begrenzte Szenarien, in denen der Datenbankanbieter in einigen Fällen in Ihrem DbContext konfiguriert ist, aber nur, wenn der Kontext noch nicht konfiguriert ist. Wenn Sie OnConfiguring
hier lassen, ist es wahrscheinlicher, dass trotz der Kompilierwarnung eine Zeichenfolge mit vertraulichen Informationen im Code verbleibt. Die zusätzliche Sicherheit und der sauberere Code, die sich aus der Entfernung dieser Methode ergeben, wurden als lohnenswert erachtet, zumal das --no-onconfiguring
- (.NET CLI) oder -NoOnConfiguring
-Flag (Visual Studio Package Manager Console) verwendet werden kann, um die Gerüstbildung der OnConfiguring
-Methode zu verhindern, und dass es anpassbare Vorlagen gibt, um IsConfigured
wieder hinzuzufügen, wenn es wirklich benötigt wird.
Gegenmaßnahmen
Entweder:
- Verwenden Sie das Argument
--no-onconfiguring
(.NET CLI) oder-NoOnConfiguring
(Visual Studio Package Manager Console), wenn Sie aus einer vorhandenen Datenbank rüsten. - Passen Sie die T4-Vorlagen an, um den Aufruf an
IsConfigured
wieder hinzuzufügen.