Udostępnij za pośrednictwem


Zmiany powodujące niezgodność w programie EF Core 8 (EF8)

Ta strona dokumentuje zmiany interfejsu API i zachowania, które mogą przerwać istniejące aplikacje aktualizowane z programu EF Core 7 do EF Core 8. 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 8 jest przeznaczony dla platformy .NET 8. Aplikacje przeznaczone dla starszych wersji platform .NET, .NET Core i .NET Framework będą musiały być aktualizowane tak, aby dotyczyły platformy .NET 8.

Podsumowanie

Zmiana powodująca niezgodność Wpływ
Contains w zapytaniach LINQ może przestać działać w starszych wersjach programu SQL Server Wys.
Wyliczenia w formacie JSON są przechowywane jako liczby ints zamiast ciągów domyślnie Wys.
Program SQL Server date i time teraz szkielet na platformie .NET DateOnly i TimeOnly Śred.
Kolumny logiczne z wygenerowaną wartością bazy danych nie są już szkieletowe jako dopuszczane do wartości null Śred.
Metody SQLite Math teraz tłumaczą się na język SQL Niski
ITypeBase zastępuje typ IEntityType w niektórych interfejsach API Niski
Wyrażenia ValueGenerator muszą używać publicznych interfejsów API Niski
ExcludeFromMigrations nie wyklucza już innych tabel w hierarchii TPC Niski
Klucze całkowite bez cienia są utrwalane w dokumentach usługi Cosmos Niski
Model relacyjny jest generowany w skompilowanym modelu Niski
Tworzenie szkieletów może generować różne nazwy nawigacji Niski
Dyskryminujące mają teraz maksymalną długość Niski
Wartości kluczy programu SQL Server są porównywane bez uwzględniania wielkości liter Niski
Wiele wywołań AddDbContext jest stosowanych w innej kolejności Niski
Metoda EntityTypeAttributeConventionBase została zastąpiona typeAttributeConventionBase Niski

Zmiany o dużym wpływie

Contains w zapytaniach LINQ może przestać działać w starszych wersjach programu SQL Server

Problem ze śledzeniem nr 13617

Stare zachowanie

Wcześniej, gdy Contains operator był używany w zapytaniach LINQ z listą wartości sparametryzowanych, program EF wygenerował program SQL, który był nieefektywny, ale pracował nad wszystkimi wersjami programu SQL Server.

Nowe zachowanie

Począwszy od programu EF Core 8.0, platforma EF generuje teraz program SQL, który jest bardziej wydajny, ale nie jest obsługiwany w programie SQL Server 2014 i poniżej.

Należy pamiętać, że nowsze wersje programu SQL Server można skonfigurować ze starszym poziomem zgodności, co również sprawia, że są one niezgodne z nowym programem SQL. Może to również wystąpić w przypadku bazy danych Azure SQL Database, która została zmigrowana z poprzedniego lokalnego wystąpienia programu SQL Server, przenosząc stary poziom zgodności.

Dlaczego

Poprzedni kod SQL wygenerowany przez program EF Core dla Contains wstawił sparametryzowane wartości jako stałe w języku SQL. Na przykład następujące zapytanie LINQ:

var names = new[] { "Blog1", "Blog2" };

var blogs = await context.Blogs
    .Where(b => names.Contains(b.Name))
    .ToArrayAsync();

... zostanie przetłumaczony na następujący kod SQL:

SELECT [b].[Id], [b].[Name]
FROM [Blogs] AS [b]
WHERE [b].[Name] IN (N'Blog1', N'Blog2')

Takie wstawianie wartości stałych do bazy danych SQL powoduje wiele problemów z wydajnością, pokonując buforowanie planu zapytań i powodując niepotrzebne eksmisji innych zapytań. Nowe tłumaczenie programu EF Core 8.0 używa funkcji PROGRAMU SQL Server OPENJSON , aby zamiast tego przenieść wartości jako tablicę JSON. Rozwiązuje to problemy z wydajnością związane z poprzednią techniką; OPENJSON jednak funkcja jest niedostępna w programie SQL Server 2014 i nowszym.

Aby uzyskać więcej informacji na temat tej zmiany, zobacz ten wpis w blogu.

Środki zaradcze

Jeśli baza danych to SQL Server 2016 (13.x) lub nowsza, lub jeśli używasz usługi Azure SQL, sprawdź skonfigurowany poziom zgodności bazy danych za pomocą następującego polecenia:

SELECT name, compatibility_level FROM sys.databases;

Jeśli poziom zgodności jest niższy niż 130 (SQL Server 2016), rozważ zmodyfikowanie go do nowszej wartości (dokumentacja).

W przeciwnym razie, jeśli wersja bazy danych jest naprawdę starsza niż SQL Server 2016 lub jest ustawiona na stary poziom zgodności, którego nie można zmienić z jakiegoś powodu, skonfiguruj program EF Core, aby przywrócić starszy, mniej wydajny program SQL w następujący sposób:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseSqlServer(@"<CONNECTION STRING>", o => o.UseCompatibilityLevel(120));

Wyliczenia w formacie JSON są przechowywane jako liczby ints zamiast ciągów domyślnie

Problem ze śledzeniem nr 13617

Stare zachowanie

W programie EF7 wyliczenia mapowane na format JSON są domyślnie przechowywane jako wartości ciągu w dokumencie JSON.

Nowe zachowanie

Począwszy od programu EF Core 8.0, ef teraz domyślnie mapuje wyliczenia na wartości całkowite w dokumencie JSON.

Dlaczego

Program EF zawsze mapował wyliczenia na kolumnę liczbową w relacyjnych bazach danych. Ponieważ program EF obsługuje zapytania, w których wartości z formatu JSON współdziałają z wartościami z kolumn i parametrów, ważne jest, aby wartości w formacie JSON odpowiadały wartościom w kolumnie innej niż JSON.

Środki zaradcze

Aby kontynuować korzystanie z ciągów, skonfiguruj właściwość wyliczenia za pomocą konwersji. Na przykład:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>().Property(e => e.Status).HasConversion<string>();
}

Lub dla wszystkich właściwości typu wyliczenia::

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder.Properties<StatusEnum>().HaveConversion<string>();
}

Zmiany o średnim wpływie

Program SQL Server date i time teraz szkielet na platformie .NET DateOnly i TimeOnly

Problem ze śledzeniem nr 24507

Stare zachowanie

Wcześniej podczas tworzenia szkieletu bazy danych programu SQL Server z kolumnami date lub time program EF wygenerował właściwości jednostki z typami DateTime i TimeSpan.

Nowe zachowanie

Począwszy od programu EF Core 8.0 i date time są szkieletowe jako DateOnly i TimeOnly.

Dlaczego

DateOnly i TimeOnly zostały wprowadzone na platformie .NET 6.0 i są idealnym dopasowaniem do mapowania typów daty i godziny bazy danych. DateTime w szczególności zawiera składnik czasu, który przechodzi nieużywane i może powodować zamieszanie podczas mapowania go na date, i TimeSpan reprezentuje interwał czasu — ewentualnie w tym dni — a nie godzinę, w której występuje zdarzenie. Użycie nowych typów zapobiega błędom i nieporozumieniu oraz zapewnia przejrzystość intencji.

Środki zaradcze

Ta zmiana dotyczy tylko użytkowników, którzy regularnie ponownie tworzyją szkielet bazy danych w modelu kodu EF ("database-first" flow).

Zaleca się zareagowanie na tę zmianę przez zmodyfikowanie kodu w celu użycia nowo utworzonych DateOnly szkieletów i TimeOnly typów. Jeśli jednak nie jest to możliwe, możesz edytować szablony tworzenia szkieletów, aby przywrócić poprzednie mapowanie. W tym celu skonfiguruj szablony zgodnie z opisem na tej stronie. Następnie zmodyfikuj EntityType.t4 plik, znajdź miejsce wygenerowania właściwości jednostki (wyszukaj property.ClrTypeciąg ), a następnie zmień kod na następujący:

        var clrType = property.GetColumnType() switch
        {
            "date" when property.ClrType == typeof(DateOnly) => typeof(DateTime),
            "date" when property.ClrType == typeof(DateOnly?) => typeof(DateTime?),
            "time" when property.ClrType == typeof(TimeOnly) => typeof(TimeSpan),
            "time" when property.ClrType == typeof(TimeOnly?) => typeof(TimeSpan?),
            _ => property.ClrType
        };

        usings.AddRange(code.GetRequiredUsings(clrType));

        var needsNullable = Options.UseNullableReferenceTypes && property.IsNullable && !clrType.IsValueType;
        var needsInitializer = Options.UseNullableReferenceTypes && !property.IsNullable && !clrType.IsValueType;
#>
    public <#= code.Reference(clrType) #><#= needsNullable ? "?" : "" #> <#= property.Name #> { get; set; }<#= needsInitializer ? " = null!;" : "" #>
<#

Kolumny logiczne z wygenerowaną wartością bazy danych nie są już szkieletowe jako dopuszczane do wartości null

Problem ze śledzeniem nr 15070

Stare zachowanie

Wcześniej kolumny bez wartości null bool z domyślnym ograniczeniem bazy danych były szkieletowe jako właściwości dopuszczane bool? do wartości null.

Nowe zachowanie

Począwszy od programu EF Core 8.0, kolumny bez wartości null bool są zawsze szkieletowe jako właściwości niepuste.

Dlaczego

Właściwość bool nie będzie mieć jej wartości wysyłanej do bazy danych, jeśli ta wartość to false, która jest wartością domyślną CLR. Jeśli baza danych ma wartość true domyślną dla kolumny, mimo że wartość właściwości to false, wartość w bazie danych kończy się jako true. Jednak w programie EF8 sentinel używany do określenia, czy właściwość ma wartość, można zmienić. Jest to wykonywane automatycznie dla bool właściwości z wygenerowaną wartością truebazy danych , co oznacza, że nie jest już konieczne utworzenie szkieletu właściwości jako dopuszczających wartość null.

Środki zaradcze

Ta zmiana dotyczy tylko użytkowników, którzy regularnie ponownie tworzyją szkielet bazy danych w modelu kodu EF ("database-first" flow).

Zaleca się zareagowanie na tę zmianę przez zmodyfikowanie kodu tak, aby używał właściwości logicznej, która nie może mieć wartości null. Jeśli jednak nie jest to możliwe, możesz edytować szablony tworzenia szkieletów, aby przywrócić poprzednie mapowanie. W tym celu skonfiguruj szablony zgodnie z opisem na tej stronie. Następnie zmodyfikuj EntityType.t4 plik, znajdź miejsce wygenerowania właściwości jednostki (wyszukaj property.ClrTypeciąg ), a następnie zmień kod na następujący:

#>
        var propertyClrType = property.ClrType != typeof(bool)
                              || (property.GetDefaultValueSql() == null && property.GetDefaultValue() != null)
            ? property.ClrType
            : typeof(bool?);
#>
    public <#= code.Reference(propertyClrType) #><#= needsNullable ? "?" : "" #> <#= property.Name #> { get; set; }<#= needsInitializer ? " = null!;" : "" #>
<#
<#

Zmiany o niskim wpływie

Metody SQLite Math teraz tłumaczą się na język SQL

Problem ze śledzeniem nr 18843

Poprzednie działanie

Wcześniej tylko metody Math Abs, Max, Min i Round zostały przetłumaczone na język SQL. Wszyscy inni członkowie będą oceniani na kliencie, jeśli pojawi się w końcowym wyrażeniu Select zapytania.

Nowe zachowanie

W programie EF Core 8.0 wszystkie Math metody z odpowiednimi funkcjami matematycznymi SQLite są tłumaczone na język SQL.

Te funkcje matematyczne zostały włączone w natywnej bibliotece SQLite, którą udostępniamy domyślnie (za pośrednictwem naszej zależności od pakietu SQLitePCLRaw.bundle_e_sqlite3 NuGet). Zostały one również włączone w bibliotece udostępnionej przez SQLitePCLRaw.bundle_e_sqlcipher. Jeśli używasz jednej z tych bibliotek, ta zmiana nie powinna mieć wpływu na aplikację.

Istnieje jednak szansa, że aplikacje, w tym natywna biblioteka SQLite, mogą nie włączać funkcji matematycznych. W takich przypadkach Math metody zostaną przetłumaczone na język SQL i nie napotkają takich błędów funkcji podczas wykonywania.

Dlaczego

SqLite dodał wbudowane funkcje matematyczne w wersji 3.35.0. Mimo że są one domyślnie wyłączone, stały się one wystarczająco wszechobecne, że postanowiliśmy udostępnić domyślne tłumaczenia dla nich w naszym dostawcy EF Core SQLite.

Współpracujemy również z Eric Sink w projekcie SQLitePCLRaw, aby umożliwić funkcje matematyczne we wszystkich natywnych bibliotekach SQLite udostępnianych w ramach tego projektu.

Środki zaradcze

Najprostszym sposobem naprawienia podziałów jest włączenie funkcji matematycznej jest natywna biblioteka SQLite, określając opcję SQLITE_ENABLE_MATH_FUNCTIONS czasu kompilacji.

Jeśli nie kontrolujesz kompilacji biblioteki natywnej, możesz również naprawić przerwy, tworząc funkcje samodzielnie w czasie wykonywania przy użyciu interfejsów API Microsoft.Data.Sqlite .

sqliteConnection
    .CreateFunction<double, double, double>(
        "pow",
        Math.Pow,
        isDeterministic: true);

Alternatywnie możesz wymusić ocenę klienta, dzieląc wyrażenie Select na dwie części oddzielone ciągami AsEnumerable.

// Before
var query = dbContext.Cylinders
    .Select(
        c => new
        {
            Id = c.Id
            // May throw "no such function: pow"
            Volume = Math.PI * Math.Pow(c.Radius, 2) * c.Height
        });

// After
var query = dbContext.Cylinders
    // Select the properties you'll need from the database
    .Select(
        c => new
        {
            c.Id,
            c.Radius,
            c.Height
        })
    // Switch to client-eval
    .AsEnumerable()
    // Select the final results
    .Select(
        c => new
        {
            Id = c.Id,
            Volume = Math.PI * Math.Pow(c.Radius, 2) * c.Height
        });

ITypeBase zastępuje typ IEntityType w niektórych interfejsach API

Problem ze śledzeniem nr 13947

Stare zachowanie

Wcześniej wszystkie mapowane typy strukturalne były typami jednostek.

Nowe zachowanie

Wraz z wprowadzeniem złożonych typów w programie EF8 niektóre interfejsy API, które były wcześniej używaneITypeBase, używają IEntityType teraz, aby interfejsy API mogły być używane z jednostkami lub typami złożonymi. Obejmuje to:

  • IProperty.DeclaringEntityType jest teraz przestarzałe i IProperty.DeclaringType należy go użyć.
  • IEntityTypeIgnoredConvention jest teraz przestarzałe i ITypeIgnoredConvention należy go użyć.
  • IValueGeneratorSelector.Selectteraz akceptuje element ITypeBase , który może być, ale nie musi być .IEntityType

Dlaczego

Wraz z wprowadzeniem złożonych typów w programie EF8 te interfejsy API mogą być używane z IEntityType programem lub IComplexType.

Środki zaradcze

Stare interfejsy API są przestarzałe, ale nie zostaną usunięte do czasu ef10. Kod powinien zostać zaktualizowany w celu korzystania z nowych interfejsów API ASAP.

Wyrażenia ValueConverter i ValueComparer muszą używać publicznych interfejsów API dla skompilowanego modelu

Problem ze śledzeniem nr 24896

Stare zachowanie

ValueConverter Wcześniej definicje i ValueComparer nie zostały uwzględnione w skompilowanym modelu, więc mogą zawierać dowolny kod.

Nowe zachowanie

Program EF wyodrębnia teraz wyrażenia z ValueConverter obiektów i ValueComparer i i uwzględnia je w skompilowanym modelu w języku C#. Oznacza to, że te wyrażenia muszą używać tylko publicznego interfejsu API.

Dlaczego

Zespół EF stopniowo przenosi kolejne konstrukcje do skompilowanego modelu w celu obsługi korzystania z platformy EF Core z funkcją AOT w przyszłości.

Środki zaradcze

Ustaw interfejsy API używane przez moduł porównujący jako publiczne. Rozważmy na przykład ten prosty konwerter:

public class MyValueConverter : ValueConverter<string, byte[]>
{
    public MyValueConverter()
        : base(v => ConvertToBytes(v), v => ConvertToString(v))
    {
    }

    private static string ConvertToString(byte[] bytes)
        => ""; // ... TODO: Conversion code

    private static byte[] ConvertToBytes(string chars)
        => Array.Empty<byte>(); // ... TODO: Conversion code
}

Aby użyć tego konwertera w skompilowanym modelu z platformą EF8, ConvertToString metody i ConvertToBytes muszą być upublicznione. Na przykład:

public class MyValueConverter : ValueConverter<string, byte[]>
{
    public MyValueConverter()
        : base(v => ConvertToBytes(v), v => ConvertToString(v))
    {
    }

    public static string ConvertToString(byte[] bytes)
        => ""; // ... TODO: Conversion code

    public static byte[] ConvertToBytes(string chars)
        => Array.Empty<byte>(); // ... TODO: Conversion code
}

ExcludeFromMigrations nie wyklucza już innych tabel w hierarchii TPC

Problem ze śledzeniem #30079

Stare zachowanie

Wcześniej użycie w ExcludeFromMigrations tabeli w hierarchii TPC wykluczało również inne tabele w hierarchii.

Nowe zachowanie

Począwszy od programu EF Core 8.0, ExcludeFromMigrations nie ma wpływu na inne tabele.

Dlaczego

Stare zachowanie było usterką i uniemożliwiło migracje używane do zarządzania hierarchiami między projektami.

Środki zaradcze

Użyj ExcludeFromMigrations jawnie dowolnej innej tabeli, która powinna zostać wykluczona.

Klucze całkowite bez cienia są utrwalane w dokumentach usługi Cosmos

Problem ze śledzeniem nr 31664

Stare zachowanie

Wcześniej właściwości liczb całkowitych innych niż w tle, które spełniają kryteria syntetyzowanej właściwości klucza, nie zostaną utrwalone w dokumencie JSON, ale zamiast tego zostały ponownie zsyntetyzowane w drodze.

Nowe zachowanie

Począwszy od programu EF Core 8.0, te właściwości są teraz utrwalane.

Dlaczego

Stare zachowanie było usterką i uniemożliwiało utrwalanie właściwości pasujących do syntetyzowanych kluczowych kryteriów do usługi Cosmos.

Środki zaradcze

Wyklucz właściwość z modelu , jeśli jej wartość nie powinna być utrwalana. Ponadto możesz całkowicie wyłączyć to zachowanie, ustawiając Microsoft.EntityFrameworkCore.Issue31664 przełącznik AppContext na true, zobacz AppContext dla użytkowników biblioteki, aby uzyskać więcej szczegółów.

AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue31664", isEnabled: true);

Model relacyjny jest generowany w skompilowanym modelu

Problem ze śledzeniem nr 24896

Stare zachowanie

Wcześniej model relacyjny został obliczony w czasie wykonywania nawet w przypadku korzystania z skompilowanego modelu.

Nowe zachowanie

Począwszy od programu EF Core 8.0, model relacyjny jest częścią wygenerowanego skompilowanego modelu. Jednak w przypadku szczególnie dużych modeli wygenerowany plik może nie zostać skompilowany.

Dlaczego

Zostało to zrobione, aby jeszcze bardziej poprawić czas uruchamiania.

Środki zaradcze

Edytuj wygenerowany *ModelBuilder.cs plik i usuń wiersz AddRuntimeAnnotation("Relational:RelationalModel", CreateRelationalModel()); , a także metodę CreateRelationalModel().

Tworzenie szkieletów może generować różne nazwy nawigacji

Problem ze śledzeniem nr 27832

Stare zachowanie

Wcześniej podczas tworzenia DbContext szkieletu typów jednostek i z istniejącej bazy danych nazwy nawigacji relacji były czasami pochodzące z wspólnego prefiksu wielu nazw kolumn kluczy obcych.

Nowe zachowanie

Począwszy od programu EF Core 8.0, typowe prefiksy nazw kolumn z złożonego klucza obcego nie są już używane do generowania nazw nawigacji.

Dlaczego

Jest to niejasna reguła nazewnictwa, która czasami generuje bardzo słabe nazwy, takie jak , S, Student_lub nawet tylko _. Bez tej reguły dziwne nazwy nie są już generowane, a konwencje nazewnictwa nawigacji są również prostsze, co ułatwia zrozumienie i przewidywanie, które nazwy zostaną wygenerowane.

Środki zaradcze

Narzędzia EF Core Power Tools mają możliwość utrzymywania generowania nawigacji w stary sposób. Alternatywnie wygenerowany kod można w pełni dostosować przy użyciu szablonów T4. Może to służyć do przykładu właściwości klucza obcego relacji tworzenia szkieletu i używania dowolnej reguły właściwej dla kodu w celu wygenerowania potrzebnych nazw nawigacji.

Dyskryminujące mają teraz maksymalną długość

Problem ze śledzeniem #10691

Stare zachowanie

Wcześniej kolumny dyskryminujące utworzone na potrzeby mapowania dziedziczenia TPH zostały skonfigurowane tak jak nvarchar(max) w programie SQL Server/Azure SQL lub równoważnym niezwiązanym typie ciągu w innych bazach danych.

Nowe zachowanie

Począwszy od programu EF Core 8.0, kolumny dyskryminujące są tworzone z maksymalną długością obejmującą wszystkie znane wartości dyskryminujące. Program EF wygeneruje migrację, aby wprowadzić tę zmianę. Jeśli jednak kolumna dyskryminująca jest ograniczona w jakiś sposób — na przykład w ramach indeksu — AlterColumn tworzenie przez migracje może zakończyć się niepowodzeniem.

Dlaczego

nvarchar(max) kolumny są nieefektywne i niepotrzebne, gdy są znane długości wszystkich możliwych wartości.

Środki zaradcze

Rozmiar kolumny można jawnie cofnąć:

modelBuilder.Entity<Foo>()
    .Property<string>("Discriminator")
    .HasMaxLength(-1);

Wartości kluczy programu SQL Server są porównywane bez uwzględniania wielkości liter

Problem ze śledzeniem nr 27526

Stare zachowanie

Wcześniej podczas śledzenia jednostek przy użyciu kluczy ciągów u dostawców usług SQL Server/Azure SQL Database wartości kluczy były porównywane przy użyciu domyślnego porównania porządkowego uwzględniającego wielkość liter platformy .NET.

Nowe zachowanie

Począwszy od programu EF Core 8.0, wartości klucza ciągu SQL Server/Azure SQL są porównywane przy użyciu domyślnego modułu porównywania wielkości liter platformy .NET bez uwzględniania wielkości liter.

Dlaczego

Domyślnie program SQL Server używa porównań bez uwzględniania wielkości liter podczas porównywania wartości klucza obcego dla dopasowań do wartości klucza głównego. Oznacza to, że gdy program EF używa porównań z uwzględnieniem wielkości liter, może nie łączyć klucza obcego z kluczem głównym, gdy powinien.

Środki zaradcze

Porównania z uwzględnieniem wielkości liter mogą być używane przez ustawienie niestandardowego ValueComparer. Na przykład:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var comparer = new ValueComparer<string>(
        (l, r) => string.Equals(l, r, StringComparison.Ordinal),
        v => v.GetHashCode(),
        v => v);

    modelBuilder.Entity<Blog>()
        .Property(e => e.Id)
        .Metadata.SetValueComparer(comparer);

    modelBuilder.Entity<Post>(
        b =>
        {
            b.Property(e => e.Id).Metadata.SetValueComparer(comparer);
            b.Property(e => e.BlogId).Metadata.SetValueComparer(comparer);
        });
}

Wiele wywołań AddDbContext jest stosowanych w innej kolejności

Problem ze śledzeniem nr 32518

Stare zachowanie

Wcześniej, gdy wiele wywołań metody AddDbContext, AddDbContextPoolAddDbContextFactory lub AddPooledDbContextFactor zostało wykonanych z tym samym typem kontekstu, ale konfiguracja powodująca konflikt, pierwsza wygrała.

Nowe zachowanie

Począwszy od programu EF Core 8.0, konfiguracja z ostatniego wywołania będzie mieć pierwszeństwo.

Dlaczego

Ta zmiana została zmieniona tak, aby była zgodna z nową metodą ConfigureDbContext , która może służyć do dodawania konfiguracji przed metodami lub po nich Add* .

Środki zaradcze

Odwraca kolejność wywołań Add* .

Metoda EntityTypeAttributeConventionBase została zastąpiona typeAttributeConventionBase

Nowe zachowanie

W programie EF Core 8.0 EntityTypeAttributeConventionBase zmieniono nazwę na TypeAttributeConventionBase.

Dlaczego

TypeAttributeConventionBase reprezentuje funkcjonalność lepszą, ponieważ teraz może być używana dla typów złożonych i typów jednostek.

Środki zaradcze

Zastąp EntityTypeAttributeConventionBase wartości użycia ciągiem TypeAttributeConventionBase.