Megosztás a következőn keresztül:


Az EF Core 8 (EF8) jelentős változásai

Ez a lap olyan API- és viselkedésváltozásokat dokumentál, amelyek megszakítják a meglévő alkalmazások EF Core 7-ről EF Core 8-ra való frissítését. Mindenképpen tekintse át a korábbi kompatibilitástörő módosításokat, ha az EF Core egy korábbi verziójáról frissít:

Cél-keretrendszer

Az EF Core 8 a .NET 8-at célozza meg. A régebbi .NET-, .NET Core- és .NET-keretrendszerverziókat megcélzó alkalmazásoknak frissítenie kell a .NET 8-at.

Összefoglalás

kompatibilitást megszakító változás hatás
Contains LINQ-lekérdezésekben leállhat a régebbi SQL Server-verziók használata Magas
A LINQ-lekérdezések Contains körüli lehetséges lekérdezési teljesítményregressziók Magas
JSON-ban lévő enumerálások alapértelmezés szerint sztringek helyett intsekként vannak tárolva Magas
SQL Server mostantól date és time számára .NET-hez (DateOnly és TimeOnly) a megjelenítést biztosítja. Közepes
adatbázis által létrehozott értékkel rendelkező logikai oszlopok többé nem lesznek null értékű Közepes
SQLite Math függvények mostantól SQL--re fordítódnak Alacsony
ITypeBase az IEntityType-t váltja fel egyes API-kban Alacsony
ValueGenerator-kifejezéseknek nyilvános API-kat kell használniuk Alacsony
ExcludeFromMigrations többé nem zárja ki a TPC-hierarchiában lévő többi táblát Alacsony
Nem árnyékolt egész szám kulcsok megmaradnak a Cosmos-dokumentumokban Alacsony
relációs modell a lefordított modellben jön létre Alacsony
Az állványok különféle navigációs neveket hozhatnak létre Alacsony
A diszkriminátorok mostantól maximális hosszúságot kaptak Alacsony
SQL Server-kulcsértékeket kis- és nagybetű érzékenység nélkül hasonlítják össze Alacsony
Több AddDbContext-hívás különböző sorrendben lesz alkalmazva Alacsony
EntityTypeAttributeConventionBase helyett TypeAttributeConventionBase Alacsony

Nagy hatású változások

Contains LINQ-lekérdezésekben leállhat a régebbi SQL Server-verziók használata

nyomon követési probléma #13617

Régi viselkedés

Az EF speciális támogatást nyújtott az Contains operátort használó LINQ-lekérdezésekhez egy paraméteres értéklistán:

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

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

Az EF Core 8.0 előtt az EF állandóként szúrta be a paraméteres értékeket az SQL-be:

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

Új viselkedés

Az EF Core 8.0-tól kezdve az EF már több esetben hatékonyabb SQL-t hoz létre, de nem támogatott az SQL Server 2014-ben és az alábbi esetekben:

SELECT [b].[Id], [b].[Name]
FROM [Blogs] AS [b]
WHERE [b].[Name] IN (
    SELECT [n].[value]
    FROM OPENJSON(@__names_0) WITH ([value] nvarchar(max) '$') AS [n]
)

Vegye figyelembe, hogy az újabb SQL Server-verziók konfigurálhatók egy régebbi kompatibilitási szinttelis, ami szintén nem kompatibilis az új SQL-vel. Ez egy olyan Azure SQL-adatbázis esetében is előfordulhat, amelyet egy korábbi helyszíni SQL Server-példányról migráltak, és amely a régi kompatibilitási szintet viszi át.

Miért

Az állandó értékek SQL-be való beszúrása számos teljesítményproblémát okoz, és megszünteti a lekérdezésterv gyorsítótárazását, és más lekérdezések szükségtelen kizárását okozza. Az új EF Core 8.0-fordítás az SQL Server OPENJSON függvénnyel továbbítja az értékeket JSON-tömbként. Ez megoldja az előző technikában rejlő teljesítményproblémákat; az OPENJSON függvény azonban nem érhető el az SQL Server 2014-ben és az alatt.

A módosításról további információt ebben a blogbejegyzésben talál.

Enyhítések

Ha az adatbázis SQL Server 2016 (13.x) vagy újabb, vagy ha Azure SQL-t használ, ellenőrizze az adatbázis konfigurált kompatibilitási szintjét az alábbi paranccsal:

SELECT name, compatibility_level FROM sys.databases;

Ha a kompatibilitási szint 130 alatt van (SQL Server 2016), fontolja meg a módosítását egy újabb értékre (lásd adokumentációban).

Ellenkező esetben, ha az adatbázis verziója valóban régebbi az SQL Server 2016-nál, vagy egy régi kompatibilitási szintre van beállítva, amelyet valamilyen okból nem tud módosítani, konfigurálhatja az EF-t a régebbi, 8.0 előtti SQL-re való visszatérésre. Ha EF 9-et használ, használhatja az újonnan bevezetett TranslateParameterizedCollectionsToConstants:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.UseSqlServer("<CONNECTION STRING>", o => o.TranslateParameterizedCollectionsToConstants())

Ha EF 8-at használ, ugyanezt a hatást érheti el az SQL Server használatakor az EF SQL-kompatibilitási szintjének konfigurálásával:

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

Lehetséges lekérdezési teljesítményregressziók a LINQ-lekérdezések Contains körül

Követési probléma #32394

Régi viselkedés

Az EF speciális támogatást nyújtott az Contains operátort használó LINQ-lekérdezésekhez egy paraméteres értéklistán:

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

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

Az EF Core 8.0 előtt az EF állandóként szúrta be a paraméteres értékeket az SQL-be:

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

Új viselkedés

Az EF Core 8.0-tól kezdve az EF a következőket hozza létre:

SELECT [b].[Id], [b].[Name]
FROM [Blogs] AS [b]
WHERE [b].[Name] IN (
    SELECT [n].[value]
    FROM OPENJSON(@__names_0) WITH ([value] nvarchar(max) '$') AS [n]
)

Az EF 8 megjelenése után azonban kiderült, hogy bár az új SQL a legtöbb esetben hatékonyabb, az esetek egy részének jelentős mértékben kevésbé hatékony lehet, még a lekérdezések időtúllépését is okozhatja bizonyos esetekben.

Ebben a megjegyzésben összefoglalást találhat az EF 8 változásáról, az EF 9-ben biztosított részleges kockázatcsökkentésekről, valamint az EF 10 tervéről.

Enyhítő intézkedések

Ha EF 9-et használ, az újonnan bevezetett TranslateParameterizedCollectionsToConstants használatával visszaállíthatja a Contains fordítást az összes lekérdezés esetében a 8.0 előtti működésre:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.UseSqlServer("<CONNECTION STRING>", o => o.TranslateParameterizedCollectionsToConstants())

Ha EF 8-at használ, ugyanezt a hatást érheti el az SQL Server használatakor az EF SQL-kompatibilitási szintjének konfigurálásával:

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

Végül a következő EF.Constant használatával szabályozhatja a lekérdezésenkénti fordítást:

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

A JSON-ban lévő enumerálások alapértelmezés szerint sztringek helyett intsekként vannak tárolva

nyomon követési probléma #13617

Régi viselkedés

Az EF7-ben a JSON- leképezett enumerálások alapértelmezés szerint sztringértékekként vannak tárolva a JSON-dokumentumban.

Új viselkedés

Az EF Core 8.0-tól kezdve az EF alapértelmezés szerint a JSON-dokumentumban az enumokat egész számokká képezi le.

Miért

Az EF alapértelmezés szerint mindig numerikus oszlopra képezte le a számokat a relációs adatbázisokban. Mivel az EF támogatja azokat a lekérdezéseket, amelyekben a JSON-értékek az oszlopokból és paraméterekből származó értékekkel kommunikálnak, fontos, hogy a JSON értékei egyezzenek a nem JSON oszlop értékeivel.

Enyhítő intézkedések

A sztringek használatának folytatásához konfigurálja az enum tulajdonságot átalakítással. Például:

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

Vagy az enum típusú összes tulajdonság esetében:

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

Közepes hatású változások

Az SQL Server date és time mostantól alapkeretként készülnek a .NET DateOnly és TimeOnly rendszerhez.

Nyomon követési probléma #24507

Régi viselkedés

Korábban, amikor egy SQL Server-adatbázist date vagy time oszlopokkal hoz létre, az EF entitástulajdonságokat hoz létre DateTime és TimeSpantípusokkal.

Új viselkedés

Az EF Core 8.0-tól kezdve, a date és time elemek DateOnly és TimeOnlyelemekké lesznek generálva.

Miért

DateOnly és TimeOnly a .NET 6.0-ban vezették be, és tökéletes egyezést jelentenek az adatbázis dátum- és időtípusainak megfeleltetéséhez. DateTime olyan időösszetevőt tartalmaz, amely nem használt, és zavart okozhat a dateleképezésekor, és TimeSpan egy időintervallumot jelöl – akár napokat is –, nem pedig egy olyan időpontot, amikor egy esemény bekövetkezik. Az új típusok használata megakadályozza a hibákat és a zavart, és egyértelmű szándékot biztosít.

Enyhítések

Ez a változás csak azokat a felhasználókat érinti, amelyek rendszeresen újraszerkesztik az adatbázist egy EF-kódmodellben ("adatbázis-első" folyamat).

Javasoljuk, hogy reagáljon erre a változásra úgy, hogy módosítja a kódot az újonnan kiépített DateOnly és TimeOnly típusok használatára. Ha azonban ez nem lehetséges, szerkesztheti az állványzatsablonokat, hogy visszatérjen az előző leképezéshez. Ehhez állítsa be a sablonokat a oldalon található leírás szerint. Ezután szerkessze a EntityType.t4 fájlt, keresse meg az entitástulajdonságok létrehozásának helyét (keressen rá a property.ClrType), és módosítsa a kódot a következőre:

        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!;" : "" #>
<#

Az olyan logikai oszlopok, amelyek adatbázisban generált értékkel rendelkeznek, többé nem kerülnek alapszinten nullable-ként beállításra.

nyomon követési probléma #15070

Régi viselkedés

Korábban a nem null értékű bool adatbázis alapértelmezett korlátozással rendelkező oszlopai null értékű bool? tulajdonságokként lettek létrehozva.

Új viselkedés

Az EF Core 8.0-tól kezdve a nem null értékű bool oszlopok mindig nem null értékű tulajdonságokként vannak létrehozva.

Miért

A bool tulajdonság értéke nem lesz elküldve az adatbázisba, ha ez az érték false, ami a CLR alapértelmezett értéke. Ha az adatbázis alapértelmezett értéke true az oszlophoz, akkor annak ellenére, hogy a tulajdonság értéke false, az adatbázis értéke truelesz. Az EF8-ban azonban a sentinel azt határozza meg, hogy egy tulajdonság rendelkezik-e értékkel, módosítható. Ez automatikusan megtörténik booltrueadatbázis által generált értékkel rendelkező tulajdonságok esetében, ami azt jelenti, hogy a tulajdonságokat már nem kell null értékűként létrehozni.

Enyhítő intézkedések

Ez a változás csak azokat a felhasználókat érinti, amelyek rendszeresen újraszerkesztik az adatbázist egy EF-kódmodellben ("adatbázis-első" folyamat).

Javasoljuk, hogy reagáljon erre a változásra úgy, hogy módosítja a kódot a nem null értékű bool tulajdonság használatára. Ha azonban ez nem lehetséges, szerkesztheti az állványzatsablonokat, hogy visszatérjen az előző leképezéshez. Ehhez állítsa be a sablonokat az ezen a lapon leírtak szerint . Ezután szerkessze a EntityType.t4 fájlt, keresse meg az entitástulajdonságok létrehozásának helyét (keressen rá a property.ClrType), és módosítsa a kódot a következőre:

#>
        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!;" : "" #>
<#
<#

Kis hatású módosítások

Az SQLite Math metódusok mostantól SQL-nek lesznek lefordítva

nyomon követési probléma #18843

Régi viselkedés

Korábban csak a Math Abs, Max, Min és Round metódusai lettek lefordítva AZ SQL-be. Az összes többi tag kiértékelése az ügyfélen történik, ha megjelennek egy lekérdezés végleges Select kifejezésében.

Új viselkedés

Az EF Core 8.0-ban a megfelelő SQLite matematikai függvényekkel rendelkező Math metódusok SQL-be lesznek lefordítva.

Ezek a matematikai függvények engedélyezve lettek a natív SQLite-kódtárban, amelyet alapértelmezés szerint biztosítunk (a SQLitePCLRaw.bundle_e_sqlite3 NuGet-csomagtól való függőségünk révén). A SQLitePCLRaw.bundle_e_sqlcipher által biztosított kódtárban is engedélyezve vannak. Ha ezen kódtárak egyikét használja, a módosítás nem érinti az alkalmazást.

Van azonban esély arra, hogy az alkalmazások, beleértve a natív SQLite-kódtárat, más módon nem teszik lehetővé a matematikai függvényeket. Ezekben az esetekben a Math metódusok SQL-re lesznek fordítva, ami nincs ilyen függvény hibákhoz vezet végrehajtáskor.

Miért

Az SQLite beépített matematikai függvényeket adott hozzá a 3.35.0-s verzióban. Annak ellenére, hogy alapértelmezés szerint le vannak tiltva, annyira áthatóvá váltak, hogy úgy döntöttünk, hogy alapértelmezett fordításokat biztosítunk számukra az EF Core SQLite-szolgáltatónkban.

Az SQLitePCLRaw projektben Eric Sinkal is együttműködtünk, hogy a projekt részeként biztosított összes natív SQLite-kódtárban engedélyezzük a matematikai függvényeket.

Enyhítések

A törések kijavításának legegyszerűbb módja, ha lehetséges, a matematikai függvényt engedélyezzük a natív SQLite könyvtárban a SQLITE_ENABLE_MATH_FUNCTIONS fordítási idejű opció megadásával.

Ha nem szabályozza a natív kódtár fordítását, a microsoft.data.sqlite API-k segítségével saját maga is létrehozhatja a függvényeket futásidőben.

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

Alternatív megoldásként kényszerítheti a kliensoldali értékelést úgy, hogy a Select kifejezést két részre osztja, amelyeket AsEnumerableválaszt el.

// 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
        });

Az ITypeBase az IEntityType-t váltja fel egyes API-kban

nyomon követési probléma #13947

Régi viselkedés

Korábban az összes leképezett szerkezeti típus entitástípusok voltak.

Új viselkedés

Az EF8 összetett típusainak bevezetésével a korábban IEntityType használt API-k most már ITypeBase használnak, hogy az API-k entitásokkal vagy összetett típusokkal is használhatók legyenek. Ez a következőket foglalja magában:

  • IProperty.DeclaringEntityType elavult, és inkább IProperty.DeclaringType kell használni.
  • IEntityTypeIgnoredConvention elavult, és inkább ITypeIgnoredConvention kell használni.
  • IValueGeneratorSelector.Select most elfogad egy ITypeBase, amely lehet, de nem kell egy IEntityType.

Miért

Az EF8 komplex típusainak bevezetésével ezek az API-k használhatók akár a IEntityType-val, akár a IComplexType-gyel.

Enyhítések

A régi API-k elavultak, de az EF10-ig nem lesznek eltávolítva. A kódot frissíteni kell az új API-k ASAP-jának használatához.

A ValueConverter és a ValueComparer kifejezéseknek nyilvános API-kat kell használniuk a lefordított modellhez

nyomon követési probléma #24896

Régi viselkedés

Korábban ValueConverter és ValueComparer definíciók nem szerepeltek a lefordított modellben, így tetszőleges kódot tartalmazhattak.

Új viselkedés

Az EF most kinyeri a kifejezéseket a ValueConverter és ValueComparer objektumokból, és tartalmazza ezeket a C#-okat a lefordított modellben. Ez azt jelenti, hogy ezeknek a kifejezéseknek csak nyilvános API-t kell használniuk.

Miért

Az EF csapata fokozatosan több szerkezetet helyez át a lefordított modellbe, hogy a jövőben támogassa az EF Core és az AOT használatát.

Enyhítése

Tegye nyilvánossá a összehasonlító által használt API-kat. Vegyük például ezt az egyszerű konvertert:

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
}

Ahhoz, hogy ezt a konvertert EF8-nal lefordított modellben használhassa, a ConvertToString és ConvertToBytes metódusoknak nyilvánosnak kell lenniük. Például:

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
}

Az ExcludeFromMigrations már nem zár ki más táblákat egy TPC-hierarchiában

Nyomkövetési probléma #30079

Régi viselkedés

Korábban a ExcludeFromMigrations TPC-hierarchiában lévő táblán való használata a hierarchiában lévő többi táblát is kizárná.

Új viselkedés

Az EF Core 8.0-tól kezdve a ExcludeFromMigrations nem befolyásolja a többi táblát.

Miért

A régi viselkedés hiba volt, és megakadályozta a migrálást a különböző projektek hierarchiáinak kezelésére.

Enyhítések

Használja a ExcludeFromMigrations-t kifejezetten bármely más táblán, amelyet ki kell zárni.

A nem árnyékolt egész számbillentyűk megmaradnak a Cosmos-dokumentumokban

nyomon követési probléma #31664

Régi viselkedés

Korábban a szintetizált kulcstulajdonságok feltételeinek megfelelő nem árnyék típusú egész számtulajdonságok nem kerültek tárolásra a JSON-dokumentumban, hanem kimenetkor újra szintetizálódtak.

Új viselkedés

Az EF Core 8.0-tól kezdve ezek a tulajdonságok megmaradnak.

Miért

A régi viselkedés hiba volt, és megakadályozta, hogy a szintetizált kulcsfeltételeknek megfelelő tulajdonságok megmaradjanak a Cosmosban.

Enyhítések

A tulajdonság kizárása a modellből, ha az értéke nem őrizhető meg. Emellett teljes mértékben letilthatja ezt a viselkedést, ha a Microsoft.EntityFrameworkCore.Issue31664 AppContext kapcsolót trueértékre állítja. További részletekért lásd a AppContext-et a könyvtárhasználók számára.

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

A relációs modell a lefordított modellben jön létre.

nyomon követési probléma #24896

Régi viselkedés

Korábban a relációs modellt futásidőben számították ki, még lefordított modell használata esetén is.

Új viselkedés

Az EF Core 8.0-tól kezdve a relációs modell a létrehozott generált modell része. Különösen nagy modellek esetén azonban előfordulhat, hogy a létrehozott fájl fordítása sikertelen.

Miért

Ez az indítási idő további javítása érdekében történt.

Enyhítések

Szerkessze a létrehozott *ModelBuilder.cs fájlt, és távolítsa el a sor AddRuntimeAnnotation("Relational:RelationalModel", CreateRelationalModel());, valamint a metódus CreateRelationalModel().

Az állványzatok különböző navigációs neveket hozhatnak létre

nyomon követési probléma #27832

Régi viselkedés

Korábban, amikor meglévő adatbázisból generálták a DbContext-t és az entitástípusokat, a kapcsolatok navigációs nevei néha több idegen kulcs-oszlopnév közös előtagjából származtak.

Új viselkedés

Az EF Core 8.0-tól kezdődően az összetett idegen kulcsból származó oszlopnevek közös előtagja már nem használható navigációs nevek létrehozásához.

Miért

Ez egy homályos elnevezési szabály, amely néha nagyon rossz neveket hoz létre, például S, Student_vagy akár csak _. E szabály nélkül a rendszer már nem hoz létre furcsa neveket, és a navigációs elnevezési konvenciók is egyszerűbbé válik, így könnyebben érthetővé és előrejelezhetővé válik, hogy mely nevek lesznek létrehozva.

Mérséklő intézkedések

Az EF Core Power Tools lehetőséget kínál arra, hogy továbbra is a régi módon hozza létre a navigációkat. Másik lehetőségként a létrehozott kód teljesen testre szabható T4-sablonokhasználatával. Ez felhasználható az állvány kapcsolatok idegen kulcs tulajdonságainak szemléltetésére, és alkalmazhat bármilyen szabályt, amely megfelelő a kódjához, hogy létrehozza a szükséges navigációs neveket.

A diszkriminátoroknak mostantól maximális hosszúságuk van.

nyomon követési probléma #10691

Régi viselkedés

Korábban a TPH-öröklés-leképezési létrehozott diszkriminatív oszlopok nvarchar(max) ként lettek konfigurálva az SQL Serveren/Azure SQL-en, vagy más adatbázisokon ezzel egyenértékű kötetlen sztringtípusként.

Új viselkedés

Az EF Core 8.0-tól kezdve a diszkriminatív oszlopok maximális hosszúságúak, amelyek az összes ismert diszkriminatív értéket lefedik. Az EF létrehoz egy migrálást a módosítás elvégzéséhez. Ha azonban a diszkriminátor oszlop valamilyen módon korlátozott – például egy index részeként –, akkor a migrációk által létrehozott AlterColumn meghiúsulhat.

Miért

nvarchar(max) oszlopok nem hatékonyak és szükségtelenek, ha az összes lehetséges érték hossza ismert.

Enyhítések

Az oszlopméret kifejezetten korlátlanná tehető.

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

Az SQL Server kulcsértékeit kis- és nagybetűk érzékenysége nélkül hasonlítják össze.

nyomon követési kérdés #27526

Régi viselkedés

Korábban a sztringkulcsokkal rendelkező entitások SQL Server-/Azure SQL-adatbázis-szolgáltatókkal való nyomon követésekor a kulcsértékeket az alapértelmezett .NET-kis- és nagybetűk megkülönböztetésével hasonlították össze.

Új viselkedés

Az EF Core 8.0-tól kezdve az SQL Server/Azure SQL karakterlánckulcs értékeit az alapértelmezett, .NET nagybetűkre nem érzékeny, rendezési összehasonlítójával hasonlítjuk össze.

Miért

Alapértelmezés szerint az SQL Server kis- és nagybetűket nem érzékelyítő összehasonlításokat használ az idegen kulcsértékek és az elsődleges kulcsértékek egyezéseinek összehasonlításakor. Ez azt jelenti, hogy ha az EF megkülönbözteti a kis- és nagybetűket, előfordulhat, hogy nem csatlakoztat egy idegen kulcsot egy főkulcshoz, amikor kell.

Enyhítések

A kis- és nagybetűket megkülönböztető összehasonlítások testreszabott ValueComparerbeállítás megadásával használhatók. Például:

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);
        });
}

A rendszer több AddDbContext-hívást alkalmaz különböző sorrendben

nyomon követési probléma #32518

Régi viselkedés

Korábban, amikor a AddDbContext, AddDbContextPool, AddDbContextFactory vagy AddPooledDbContextFactor több hívása is ugyanazzal a környezettípussal, de ütköző konfigurációval történt, az első nyert.

Új viselkedés

Az EF Core 8.0-tól kezdve az utolsó hívás konfigurációja elsőbbséget élvez.

Miért

Ezt úgy módosították, hogy összhangban legyen az új ConfigureDbContext metódussal, amely a Add* metódusok előtt vagy után is konfigurálható.

Enyhítések

A Add* hívások sorrendjének megfordítása.

EntityTypeAttributeConventionBase helyett TypeAttributeConventionBase

Új viselkedés

Az EF Core 8.0-ban EntityTypeAttributeConventionBase átnevezték TypeAttributeConventionBase.

Miért

TypeAttributeConventionBase jobban képviseli a funkciót, mivel mostantól összetett típusokhoz és entitástípusokhoz is használható.

Enyhítések

Cserélje le a EntityTypeAttributeConventionBase használatokat TypeAttributeConventionBase-re.