Zmiany powodujące niezgodność w programie EF Core 7.0 (EF7)
Ta strona dokumentuje zmiany interfejsu API i zachowania, które mogą przerwać istniejące aplikacje aktualizowane z programu EF Core 6 do EF Core 7. Pamiętaj, aby przejrzeć wcześniejsze zmiany powodujące niezgodność w przypadku aktualizacji z wcześniejszej wersji programu EF Core:
Struktura docelowa
Program EF Core 7.0 jest przeznaczony dla platformy .NET 6. Oznacza to, że istniejące aplikacje przeznaczone dla platformy .NET 6 mogą nadal to robić. Aplikacje przeznaczone dla starszych wersji platform .NET, .NET Core i .NET Framework będą musiały być przeznaczone dla platformy .NET 6 lub .NET 7, aby korzystały z programu EF Core 7.0.
Podsumowanie
Zmiany o dużym wpływie
Encrypt
wartość domyślna true
dla połączeń programu SQL Server
Problem ze śledzeniem: SqlClient #1210
Ważne
Jest to poważna zmiana powodująca niezgodność w pakiecie Microsoft.Data.SqlClient . Nie ma nic, co można zrobić w programie EF Core, aby przywrócić lub złagodzić tę zmianę. Prześlij opinię do repozytorium GitHub Microsoft.Data.SqlClient lub skontaktuj się z pomoc techniczna firmy Microsoft Professional, aby uzyskać dodatkowe pytania lub pomoc.
Stare zachowanie
Program SqlClient parametry połączenia używać Encrypt=False
domyślnie. Umożliwia to nawiązywanie połączeń na maszynach deweloperskich, na których serwer lokalny nie ma prawidłowego certyfikatu.
Nowe zachowanie
Program SqlClient parametry połączenia używać Encrypt=True
domyślnie. To oznacza, że:
- Serwer musi być skonfigurowany przy użyciu prawidłowego certyfikatu
- Klient musi ufać temu certyfikatowi
Jeśli te warunki nie zostaną spełnione, zostanie zgłoszony element SqlException
. Na przykład:
Połączenie z serwerem zostało pomyślnie nawiązane, ale wystąpił błąd podczas procesu logowania. (dostawca: Dostawca SSL, błąd: 0 — łańcuch certyfikatów został wystawiony przez urząd, który nie jest zaufany).
Dlaczego
Ta zmiana została wprowadzona, aby upewnić się, że domyślnie połączenie jest bezpieczne lub aplikacja nie będzie mogła nawiązać połączenia.
Środki zaradcze
Istnieją trzy sposoby kontynuowania:
- Zainstaluj prawidłowy certyfikat na serwerze. Należy pamiętać, że jest to proces zaangażowany i wymaga uzyskania certyfikatu i upewnienia się, że jest podpisany przez urząd zaufany przez klienta.
- Jeśli serwer ma certyfikat, ale nie jest zaufany przez klienta, należy
TrustServerCertificate=True
zezwolić na pomijanie normalnego mechanizmu zaufania. - Jawnie dodaj
Encrypt=False
do parametry połączenia.
Ostrzeżenie
Opcje 2 i 3 pozostawiają serwer w stanie potencjalnie niezabezpieczonym.
Niektóre ostrzeżenia ponownie zgłaszają wyjątki
Problem ze śledzeniem nr 29069
Stare zachowanie
W programie EF Core 6.0 usterka dostawcy programu SQL Server oznaczała, że niektóre ostrzeżenia skonfigurowane do zgłaszania wyjątków domyślnie były rejestrowane, ale nie zgłaszały wyjątków. Te ostrzeżenia są następujące:
EventId | opis |
---|---|
RelationalEventId.AmbientTransactionWarning | Aplikacja mogła oczekiwać, że transakcja otoczenia będzie używana, gdy została ona rzeczywiście zignorowana. |
RelationalEventId.IndexPropertiesBothMappedAndNotMappedToTable | Indeks określa właściwości, z których niektóre są mapowane, a niektóre nie są mapowane na kolumnę w tabeli. |
RelationalEventId.IndexPropertiesMappedToNonOverlappingTables | Indeks określa właściwości mapowania na kolumny w tabelach nienakładających się. |
RelationalEventId.ForeignKeyPropertiesMappedToUnrelatedTables | Klucz obcy określa właściwości, które nie są mapowe na powiązane tabele. |
Nowe zachowanie
Począwszy od platformy EF Core 7.0, ostrzeżenia te domyślnie powodują zgłoszenie wyjątku.
Dlaczego
Są to problemy, które najprawdopodobniej wskazują błąd w kodzie aplikacji, który powinien zostać rozwiązany.
Środki zaradcze
Rozwiąż podstawowy problem, który jest przyczyną ostrzeżenia.
Alternatywnie można zmienić poziom ostrzeżenia, tak aby był rejestrowany tylko lub całkowicie pomijany. Na przykład:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.ConfigureWarnings(b => b.Ignore(RelationalEventId.AmbientTransactionWarning));
Tabele programu SQL Server z wyzwalaczami lub określonymi kolumnami obliczeniowymi wymagają teraz specjalnej konfiguracji platformy EF Core
Problem ze śledzeniem nr 27372
Stare zachowanie
Poprzednie wersje dostawcy programu SQL Server zapisywały zmiany za pomocą mniej wydajnej techniki, która zawsze działała.
Nowe zachowanie
Domyślnie program EF Core zapisuje teraz zmiany za pomocą znacznie bardziej wydajnej techniki; niestety ta technika nie jest obsługiwana w programie SQL Server, jeśli tabela docelowa zawiera wyzwalacze bazy danych lub niektóre typy kolumn obliczeniowych. Aby uzyskać więcej informacji, zobacz dokumentację programu SQL Server.
Dlaczego
Ulepszenia wydajności związane z nową metodą są wystarczająco istotne, aby domyślnie udostępnić je użytkownikom. Jednocześnie szacujemy użycie wyzwalaczy bazy danych lub kolumn obliczeniowych, których dotyczy problem, w aplikacjach EF Core, aby było wystarczająco niskie, że negatywne konsekwencje zmiany powodujące niezgodność są przeważane przez wzrost wydajności.
Środki zaradcze
Począwszy od programu EF Core 8.0, można jawnie skonfigurować użycie klauzuli "OUTPUT". Na przykład:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.UseSqlOutputClause(false));
}
W programie EF7 lub nowszym, jeśli tabela docelowa ma wyzwalacz, możesz poinformować program EF Core o tym, a program EF powróci do poprzedniej, mniej wydajnej techniki. Można to zrobić, konfigurując odpowiedni typ jednostki w następujący sposób:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.HasTrigger("SomeTrigger"));
}
Należy pamiętać, że wykonanie tej czynności nie powoduje, że program EF Core tworzy wyzwalacz ani nie zarządza nim w żaden sposób — obecnie informuje tylko program EF Core, że wyzwalacze znajdują się w tabeli. W związku z tym można użyć dowolnej nazwy wyzwalacza. Określenie wyzwalacza może służyć do przywracania starego zachowania , nawet jeśli w tabeli nie ma wyzwalacza.
Jeśli większość lub wszystkie tabele mają wyzwalacze, możesz zrezygnować z korzystania z nowszej, wydajnej techniki dla wszystkich tabel modelu przy użyciu następującej konwencji tworzenia modelu:
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");
}
}
}
}
}
Użyj konwencji dotyczącej elementu DbContext
, przesłaniając element ConfigureConventions
:
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Conventions.Add(_ => new BlankTriggerAddingConvention());
}
Skutecznie wywołuje HasTrigger
to wszystkie tabele modelu, zamiast ręcznie wykonywać je dla każdej tabeli.
Tabele SQLite z wyzwalaczami AFTER i tabelami wirtualnymi wymagają teraz specjalnej konfiguracji programu EF Core
Problem ze śledzeniem nr 29916
Stare zachowanie
Poprzednie wersje dostawcy SQLite zapisywały zmiany za pomocą mniej wydajnej techniki, która zawsze działała.
Nowe zachowanie
Domyślnie program EF Core zapisuje teraz zmiany za pomocą bardziej wydajnej techniki przy użyciu klauzuli RETURNING. Niestety ta technika nie jest obsługiwana w bazie danych SQLite, jeśli tabela docelowa ma wyzwalacze AFTER bazy danych, jest wirtualna lub jeśli są używane starsze wersje sqlite. Aby uzyskać więcej informacji, zobacz dokumentację sqlite.
Dlaczego
Uproszczenia i ulepszenia wydajności związane z nową metodą są na tyle istotne, że ważne jest, aby domyślnie udostępnić je użytkownikom. Jednocześnie szacujemy użycie wyzwalaczy bazy danych i tabel wirtualnych w aplikacjach EF Core, aby było wystarczająco niskie, że negatywne konsekwencje zmiany powodujące niezgodność są przeważane przez wzrost wydajności.
Środki zaradcze
W programie EF Core 8.0 UseSqlReturningClause
metoda została wprowadzona w celu jawnego powrotu do starszego, mniej wydajnego kodu SQL. Na przykład:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.UseSqlReturningClause(false));
}
Jeśli nadal używasz programu EF Core 7.0, można przywrócić stary mechanizm dla całej aplikacji, wstawiając następujący kod w konfiguracji kontekstu:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlite(...)
.ReplaceService<IUpdateSqlGenerator, SqliteLegacyUpdateSqlGenerator>();
Zmiany o średnim wpływie
Oddzielone zależności relacji opcjonalnych nie są usuwane automatycznie
Problem ze śledzeniem nr 27217
Stare zachowanie
Relacja jest opcjonalna , jeśli jego klucz obcy jest dopuszczany do wartości null. Ustawienie klucza obcego na wartość null umożliwia istnienie jednostki zależnej bez żadnej powiązanej jednostki głównej. Relacje opcjonalne można skonfigurować tak, aby korzystały z usuwania kaskadowego, chociaż nie jest to ustawienie domyślne.
Opcjonalna zależność może zostać odcięta od podmiotu zabezpieczeń, ustawiając jego klucz obcy na wartość null, lub czyszcząc nawigację do lub z niej. W programie EF Core 6.0 spowoduje to usunięcie zależności, gdy relacja została skonfigurowana do usuwania kaskadowego.
Nowe zachowanie
Począwszy od programu EF Core 7.0, zależne nie jest już usuwane. Należy pamiętać, że jeśli podmiot zabezpieczeń zostanie usunięty, zależne będzie nadal usuwane, ponieważ kaskadowe usunięcia są skonfigurowane dla relacji.
Dlaczego
Zależność może istnieć bez żadnej relacji z podmiotem zabezpieczeń, dlatego zerwanie relacji nie powinno spowodować usunięcia jednostki.
Środki zaradcze
Zależne można jawnie usunąć:
context.Remove(blog);
Można też SaveChanges
przesłonić lub przechwycić w celu usunięcia zależności bez odwołania podmiotu zabezpieczeń. Na przykład:
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;
}
}
};
Usuwanie kaskadowe jest konfigurowane między tabelami podczas korzystania z mapowania TPT w programie SQL Server
Problem ze śledzeniem nr 28532
Stare zachowanie
Podczas mapowania hierarchii dziedziczenia przy użyciu strategii TPT tabela podstawowa musi zawierać wiersz dla każdej zapisanej jednostki, niezależnie od rzeczywistego typu tej jednostki. Usunięcie wiersza w tabeli podstawowej powinno spowodować usunięcie wierszy we wszystkich innych tabelach. Program EF Core konfiguruje w tym celu kaskadowe usuwanie .
W programie EF Core 6.0 usterka dostawcy bazy danych programu SQL Server oznaczała, że te kaskadowe usunięcia nie zostały utworzone.
Nowe zachowanie
Począwszy od programu EF Core 7.0, kaskadowe usunięcia są teraz tworzone dla programu SQL Server tak samo jak zawsze w przypadku innych baz danych.
Dlaczego
Kaskadowe usuwanie z tabeli podstawowej do tabel podrzędnych w tabeli TPT umożliwia usunięcie jednostki przez usunięcie wiersza w tabeli podstawowej.
Środki zaradcze
W większości przypadków ta zmiana nie powinna powodować żadnych problemów. Jednak program SQL Server jest bardzo restrykcyjny, gdy istnieje wiele zachowań kaskadowych skonfigurowanych między tabelami. Oznacza to, że jeśli istnieje istniejąca relacja kaskadowa między tabelami w mapowaniu TPT, program SQL Server może wygenerować następujący błąd:
Microsoft.Data.SqlClient.SqlException: instrukcja DELETE powoduje konflikt z ograniczeniem REFERENCE "FK_Blogs_People_OwnerId". Konflikt wystąpił w bazie danych "Scratch", tabeli "dbo". Blogi", kolumna "OwnerId". Instrukcja została zakończona.
Na przykład ten model tworzy cykl kaskadowych relacji:
[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; }
}
Jedną z tych opcji należy skonfigurować tak, aby nie używać kaskadowych usuwania na serwerze. Aby na przykład zmienić jawną relację:
modelBuilder
.Entity<FeaturedPost>()
.HasOne(e => e.ReferencePost)
.WithMany()
.OnDelete(DeleteBehavior.ClientCascade);
Możesz też zmienić niejawną relację utworzoną dla mapowania TPT:
modelBuilder
.Entity<FeaturedPost>()
.HasOne<Post>()
.WithOne()
.HasForeignKey<FeaturedPost>(e => e.Id)
.OnDelete(DeleteBehavior.ClientCascade);
Większe prawdopodobieństwo zajętych/zablokowanych błędów w programie SQLite, gdy nie jest używane rejestrowanie z wyprzedzeniem zapisu
Stare zachowanie
Poprzednie wersje dostawcy SQLite zapisali zmiany za pomocą mniej wydajnej techniki, która była w stanie automatycznie ponowić próbę, gdy tabela została zablokowana/zajęta, a rejestrowanie z wyprzedzeniem zapisu (WAL) nie zostało włączone.
Nowe zachowanie
Domyślnie program EF Core zapisuje teraz zmiany za pomocą bardziej wydajnej techniki przy użyciu klauzuli RETURNING. Niestety ta technika nie jest w stanie automatycznie ponowić próby po zajęciu/zablokowaniu. W aplikacji wielowątkowa (takiej jak aplikacja internetowa) nie korzysta z rejestrowania z wyprzedzeniem zapisu, często występują te błędy.
Dlaczego
Uproszczenia i ulepszenia wydajności związane z nową metodą są na tyle istotne, że ważne jest, aby domyślnie udostępnić je użytkownikom. Bazy danych utworzone przez program EF Core również domyślnie włączają rejestrowanie z wyprzedzeniem zapisu. Zespół SQLite zaleca również domyślne włączanie rejestrowania z wyprzedzeniem zapisu.
Środki zaradcze
Jeśli to możliwe, należy włączyć rejestrowanie z wyprzedzeniem zapisu w bazie danych. Jeśli baza danych została utworzona przez program EF, powinno to już mieć miejsce. Jeśli nie, możesz włączyć rejestrowanie z wyprzedzeniem zapisu, wykonując następujące polecenie.
PRAGMA journal_mode = 'wal';
Jeśli z jakiegoś powodu nie można włączyć rejestrowania z wyprzedzeniem zapisu, można przywrócić stary mechanizm dla całej aplikacji, wstawiając następujący kod w konfiguracji kontekstu:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlite(...)
.ReplaceService<IUpdateSqlGenerator, SqliteLegacyUpdateSqlGenerator>();
Zmiany o niskim wpływie
Konieczne może być skonfigurowanie kluczowych właściwości za pomocą modułu porównującego wartości dostawcy
Problem ze śledzeniem nr 27738
Stare zachowanie
W programie EF Core 6.0 wartości klucza pobrane bezpośrednio z właściwości typów jednostek były używane do porównywania wartości kluczy podczas zapisywania zmian. Spowoduje to użycie dowolnego niestandardowego porównania wartości skonfigurowanego dla tych właściwości.
Nowe zachowanie
Począwszy od programu EF Core 7.0, wartości baz danych są używane do tych porównań. To "po prostu działa" dla zdecydowanej większości przypadków. Jeśli jednak właściwości korzystały z niestandardowego modułu porównania i tego modułu porównującego nie można zastosować do wartości bazy danych, może być potrzebny "moduł porównania wartości dostawcy", jak pokazano poniżej.
Dlaczego
Różne podziały jednostek i dzielenie tabel mogą spowodować mapowanie wielu właściwości na tę samą kolumnę bazy danych i na odwrót. Wymaga to porównania wartości po konwersji na wartość, która będzie używana w bazie danych.
Środki zaradcze
Konfigurowanie porównania wartości dostawcy. Rozważmy na przykład przypadek, w którym obiekt wartości jest używany jako klucz, a moduł porównujący dla tego klucza używa porównań ciągów bez uwzględniania wielkości liter:
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);
Wartości bazy danych (ciągi) nie mogą bezpośrednio używać porównywacza zdefiniowanego dla BlogKey
typów. W związku z tym należy skonfigurować porównanie ciągów bez uwzględniania wielkości liter przez dostawcę:
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);
Sprawdź ograniczenia i inne aspekty tabeli są teraz skonfigurowane w tabeli
Problem ze śledzeniem nr 28205
Stare zachowanie
W programie EF Core 6.0 HasCheckConstraint
wywołano metody i HasComment
IsMemoryOptimized
bezpośrednio w konstruktorze typów jednostek. Na przykład:
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();
Nowe zachowanie
Począwszy od programu EF Core 7.0, te metody są zamiast tego wywoływane w konstruktorze tabel:
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());
Istniejące metody zostały oznaczone jako Obsolete
. Obecnie mają takie samo zachowanie jak nowe metody, ale zostaną usunięte w przyszłej wersji.
Dlaczego
Te aspekty mają zastosowanie tylko do tabel. Nie będą one stosowane do żadnych zamapowanych widoków, funkcji ani procedur składowanych.
Środki zaradcze
Użyj metod konstruktora tabel, jak pokazano powyżej.
Nawigacje z nowych jednostek do usuniętych jednostek nie są naprawione
Problem ze śledzeniem nr 28249
Stare zachowanie
W programie EF Core 6.0, gdy nowa jednostka jest śledzona z zapytania śledzenia lub dołączając ją do elementu , nawigacje do DbContext
i z powiązanych jednostek wDeleted
stanie są naprawione.
Nowe zachowanie
Począwszy od programu EF Core 7.0, nawigacje do i z Deleted
jednostek nie są naprawione.
Dlaczego
Po oznaczeniu jednostki jako Deleted
rzadko warto ją skojarzyć z jednostkami, które nie zostały usunięte.
Środki zaradcze
Wykonaj zapytanie lub dołącz jednostki przed oznaczeniem jednostek jako Deleted
lub ręcznie ustaw właściwości nawigacji na i z usuniętej jednostki.
Używanie FromSqlRaw
metod i powiązanych z niewłaściwym dostawcą zgłasza metodę use-the-correct-method
Problem ze śledzeniem nr 26502
Stare zachowanie
W programie EF Core 6.0 użycie metody rozszerzenia usługi Azure Cosmos DB podczas korzystania z dostawcy relacyjnego lub metody rozszerzenia relacyjnego FromSqlRaw w przypadku korzystania z dostawcy usługi Azure Cosmos DB FromSqlRaw może dyskretnie zakończyć się niepowodzeniem. Podobnie używanie metod relacyjnych u dostawcy w pamięci jest dyskretnym no-op.
Nowe zachowanie
Począwszy od programu EF Core 7.0, użycie metody rozszerzenia zaprojektowanej dla jednego dostawcy u innego dostawcy zgłosi wyjątek.
Dlaczego
Prawidłowa metoda rozszerzenia musi być używana do prawidłowego działania we wszystkich sytuacjach.
Środki zaradcze
Użyj poprawnej metody rozszerzenia dla używanego dostawcy. Jeśli odwołuje się do wielu dostawców, wywołaj metodę rozszerzenia jako metodę statyczną. Na przykład:
var result = await CosmosQueryableExtensions.FromSqlRaw(context.Blogs, "SELECT ...").ToListAsync();
Lub:
var result = await RelationalQueryableExtensions.FromSqlRaw(context.Blogs, "SELECT ...").ToListAsync();
Szkielet nie OnConfiguring
wywołuje już wywołań IsConfigured
Stare zachowanie
W programie EF Core 6.0 DbContext
typ szkieletowy z istniejącej bazy danych zawierał wywołanie metody IsConfigured
. Na przykład:
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");
}
}
Nowe zachowanie
Począwszy od programu EF Core 7.0, wywołanie metody IsConfigured
nie jest już uwzględniane.
Dlaczego
Istnieją bardzo ograniczone scenariusze, w których dostawca bazy danych jest skonfigurowany wewnątrz elementu DbContext w niektórych przypadkach, ale tylko wtedy, gdy kontekst nie jest jeszcze skonfigurowany. Zamiast tego pozostawienie OnConfiguring
tutaj sprawia, że bardziej prawdopodobne jest, że parametry połączenia zawierający poufne informacje pozostają w kodzie, pomimo ostrzeżenia czasu kompilacji. W związku z tym dodatkowy bezpieczny i czystszy kod z usunięcia tego elementu został uznany za godny uwagi, zwłaszcza, że --no-onconfiguring
flaga (interfejs wiersza polecenia platformy .NET) lub -NoOnConfiguring
(konsola programu Visual Studio Menedżer pakietów) może służyć do zapobiegania tworzenia OnConfiguring
szkieletów metody i że możliwe do dostosowania szablony istnieją, aby dodać z powrotemIsConfigured
, jeśli jest to naprawdę potrzebne.
Środki zaradcze
Dowolny z następujących elementów:
- Użyj argumentu
--no-onconfiguring
(interfejs wiersza polecenia platformy .NET) lub-NoOnConfiguring
(Visual Studio Menedżer pakietów Console) podczas tworzenia szkieletu z istniejącej bazy danych. - Dostosuj szablony T4, aby dodać wywołanie do
IsConfigured
metody .