Dela via


Nya funktioner i EF Core 2.1

Förutom många buggkorrigeringar och små funktions- och prestandaförbättringar innehåller EF Core 2.1 några övertygande nya funktioner:

Fördröjd laddning

EF Core innehåller nu de byggstenar som krävs för att alla ska kunna skapa entitetsklasser som kan läsa in deras navigeringsegenskaper på begäran. Vi har också skapat ett nytt paket, Microsoft.EntityFrameworkCore.Proxies, som utnyttjar dessa byggstenar för att skapa lata inläsningsproxyklasser baserat på minimalt modifierade entitetsklasser (till exempel klasser med virtuella navigeringsegenskaper).

Läs avsnittet om lat inläsning för mer information om detta ämne.

Parametrar i entitetskonstruktorer

Som en av de nödvändiga byggstenarna för fördröjd inläsning har vi aktiverat skapandet av entiteter som tar parametrar i sina konstruktorer. Du kan använda parametrar för att mata in egenskapsvärden, lata inläsningsdelegater och tjänster.

Läs avsnittet om entitetskonstruktor med parametrar för mer information om det här avsnittet.

Värdekonverteringar

Hittills har EF Core bara kunnat mappa egenskaper för typer som stöds internt av den underliggande databasprovidern. Värden kopierades fram och tillbaka mellan kolumner och egenskaper utan någon transformering. Från och med EF Core 2.1 kan värdekonverteringar användas för att transformera de värden som hämtas från kolumner innan de tillämpas på egenskaper och vice versa. Vi har ett antal konverteringar som kan tillämpas av konventionen vid behov, samt ett explicit konfigurations-API som gör det möjligt att registrera anpassade konverteringar mellan kolumner och egenskaper. Några av användningsområdena för den här funktionen är:

  • Lagra enums som strängar
  • Mappa osignerade heltal med SQL Server
  • Automatisk kryptering och dekryptering av egenskapsvärden

Mer information om det här avsnittet finns i avsnittet om värdekonverteringar.

LINQ GroupBy-översättning

Före version 2.1 skulle GroupBy LINQ-operatorn i EF Core alltid utvärderas i minnet. Vi stöder nu översättning till SQL GROUP BY-satsen i de vanligaste fallen.

Det här exemplet visar en fråga med GroupBy som används för att beräkna olika mängdfunktioner:

var query = context.Orders
    .GroupBy(o => new { o.CustomerId, o.EmployeeId })
    .Select(g => new
        {
          g.Key.CustomerId,
          g.Key.EmployeeId,
          Sum = g.Sum(o => o.Amount),
          Min = g.Min(o => o.Amount),
          Max = g.Max(o => o.Amount),
          Avg = g.Average(o => o.Amount)
        });

Motsvarande SQL-översättning ser ut så här:

SELECT [o].[CustomerId], [o].[EmployeeId],
    SUM([o].[Amount]), MIN([o].[Amount]), MAX([o].[Amount]), AVG([o].[Amount])
FROM [Orders] AS [o]
GROUP BY [o].[CustomerId], [o].[EmployeeId];

Dataladdning

Med den nya versionen är det möjligt att tillhandahålla initiala data för att fylla i en databas. Till skillnad från i EF6 associeras seeding-data till en entitetstyp som en del av modellkonfigurationen. Sedan kan EF Core-migreringar automatiskt beräkna vilka infognings-, uppdaterings- eller borttagningsåtgärder som måste tillämpas när databasen uppgraderas till en ny version av modellen.

Du kan till exempel använda detta för att konfigurera startdata för ett inlägg i OnModelCreating:

modelBuilder.Entity<Post>().HasData(new Post{ Id = 1, Text = "Hello World!" });

Läs avsnittet om data seeding för mer information om detta ämne.

Frågetyper

En EF Core-modell kan nu innehålla frågetyper. Till skillnad från entitetstyper har frågetyper inte definierade nycklar och kan inte infogas, tas bort eller uppdateras (de är skrivskyddade), men de kan returneras direkt av en fråga. Några av användningsscenarierna för frågetyper är:

  • Mappa till vyer utan primära nycklar
  • Mappa till tabeller utan primära nycklar
  • Mappa till frågor som definierats i modellen
  • Fungerar som returtyp för FromSql() frågor

Mer information om det här avsnittet finns i avsnittet om frågetyper.

Inkludera för härledda typer

Nu går det att ange navigeringsegenskaper som endast definieras för härledda typer när du skriver uttryck för metoden Include. För den starkt skrivna versionen av Includestöder vi antingen explicit gjutning eller as-operatorn. Nu har vi även stöd för att referera till namnen på navigeringsegenskapen som definierats för härledda typer i strängversionen av Include:

var option1 = context.People.Include(p => ((Student)p).School);
var option2 = context.People.Include(p => (p as Student).School);
var option3 = context.People.Include("School");

Läs avsnittet om Inkludera med härledda typer för mer information om det här avsnittet.

System.Transactions-stöd

Vi har lagt till möjligheten att arbeta med System.Transactions-funktioner som TransactionScope. Detta fungerar på både .NET Framework och .NET Core när du använder databasprovidrar som stöder det.

Läs avsnittet på System.Transactions för mer information om det här avsnittet.

Bättre kolumnordning vid inledande migrering

Baserat på kundfeedback har vi uppdaterat migreringar för att initialt generera kolumner för tabeller i samma ordning som egenskaper deklareras i klasser. Observera att EF Core inte kan ändra ordning när nya medlemmar läggs till när den första tabellen har skapats.

Optimering av korrelerade underfrågor

Vi har förbättrat vår frågeöversättning för att undvika att köra "N + 1"-SQL-frågor i många vanliga scenarier där användningen av en navigeringsegenskap i projektionen leder till att data från rotfrågan kopplas till data från en korrelerad underfråga. Optimeringen kräver buffring av resultaten från underfrågan, och vi kräver att du ändrar frågan för att välja det nya beteendet.

Till exempel översätts följande fråga normalt till en fråga för Kunder, plus N (där "N" är antalet kunder som returneras) separata frågor för Beställningar:

var query = context.Customers.Select(
    c => c.Orders.Where(o => o.Amount  > 100).Select(o => o.Amount));

Genom att inkludera ToListAsync() på rätt plats anger du att buffring är lämplig för Beställningar, vilket möjliggör optimeringen:

var query = context.Customers.Select(
    c => c.Orders.Where(o => o.Amount  > 100).Select(o => o.Amount).ToList());

Observera att den här frågan endast kommer att översättas till två SQL-frågor: en för kunder och nästa för Beställningar.

Attributet [ägd]

Nu är det möjligt att konfigurera ägda entitetstyper genom att helt enkelt kommentera typen med [Owned] och sedan se till att ägarentiteten läggs till i modellen:

[Owned]
public class StreetAddress
{
    public string Street { get; set; }
    public string City { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public StreetAddress ShippingAddress { get; set; }
}

Kommandoradsverktyget dotnet-ef ingår i .NET Core SDK

Kommandona dotnet-ef ingår nu i .NET Core SDK. Därför behöver du inte längre använda DotNetCliToolReference i projektet för att kunna använda migreringar eller skapa en DbContext från en befintlig databas.

Mer information om hur du aktiverar kommandoradsverktyg för olika versioner av .NET Core SDK och EF Core finns i avsnittet om att installera verktygen.

Microsoft.EntityFrameworkCore.Abstractions-paketet

Det nya paketet innehåller attribut och gränssnitt som du kan använda i dina projekt för att lysa upp EF Core-funktioner utan att behöva använda EF Core som helhet. Attributet [Owned] och ILazyLoader-gränssnittet finns till exempel här.

Tillståndsändringshändelser

Nya Tracked och StateChanged händelser på ChangeTracker kan användas för att skriva logik som reagerar på entiteter som kommer in i DbContext eller ändrar deras status.

Rå SQL-parameteranalys

En ny kodanalys ingår i EF Core som identifierar potentiellt osäkra användningar av våra RAW-SQL-API:er, till exempel FromSql eller ExecuteSqlCommand. För följande fråga visas till exempel en varning eftersom minAge- inte har parameteriserats:

var sql = $"SELECT * FROM People WHERE Age > {minAge}";
var query = context.People.FromSql(sql);

Databasleverantörens kompatibilitet

Vi rekommenderar att du använder EF Core 2.1 med leverantörer som har uppdaterats eller åtminstone testats för att arbeta med EF Core 2.1.

Tips

Om du hittar någon oväntad inkompatibilitet eller något problem i de nya funktionerna, eller om du har feedback på dem, kan du rapportera det med hjälp av vårt problemspårare.