Sdílet prostřednictvím


Nové funkce EF Core 2.1

Kromě mnoha oprav chyb a malých vylepšení funkčnosti a výkonu ef Core 2.1 obsahuje některé zajímavé nové funkce:

Opožděné načítání

EF Core teď obsahuje potřebné stavební bloky, které mohou všichni vytvářet třídy entit, které mohou načíst své navigační vlastnosti na vyžádání. Vytvořili jsme také nový balíček Microsoft.EntityFrameworkCore.Proxies, který tyto stavební bloky využívá k vytváření opožděných tříd načítání proxy na základě minimálně upravených tříd entit (například tříd s vlastnostmi virtuální navigace).

Další informace o tomto tématu najdete v části o opožděné načítání .

Parametry v konstruktorech entit

Jako jeden z požadovaných stavebních bloků pro opožděné načítání jsme povolili vytváření entit, které v jejich konstruktorech přebírají parametry. Pomocí parametrů můžete vkládat hodnoty vlastností, opožděné načítání delegátů a služeb.

Další informace o tomto tématu najdete v části o konstruktoru entity s parametry .

Převody hodnot

Ef Core doteď může mapovat pouze vlastnosti typů nativně podporovaných podkladovým poskytovatelem databáze. Hodnoty se zkopírovaly zpět mezi sloupci a vlastnostmi bez jakékoli transformace. Počínaje ef Core 2.1 lze převody hodnot použít k transformaci hodnot získaných ze sloupců předtím, než se použijí na vlastnosti a naopak. Máme řadu převodů, které je možné podle konvence použít podle potřeby, a také explicitní konfigurační rozhraní API, které umožňuje registraci vlastních převodů mezi sloupci a vlastnostmi. Mezi aplikace této funkce patří:

  • Ukládání výčtů jako řetězců
  • Mapování celých čísel bez znaménka pomocí SQL Serveru
  • Automatické šifrování a dešifrování hodnot vlastností

Další informace o tomto tématu najdete v části o převodech hodnot.

Překlad LINQ GroupBy

Před verzí 2.1 by v EF Core byl operátor GroupBy LINQ vždy vyhodnocen v paměti. Nyní podporujeme jeho překlad do klauzule SQL GROUP BY ve většině běžných případů.

Tento příklad ukazuje dotaz se GroupBy použitým k výpočtu různých agregačních funkcí:

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

Odpovídající překlad SQL vypadá takto:

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];

Předvyplnění dat

V nové verzi bude možné poskytnout počáteční data pro naplnění databáze. Na rozdíl od EF6 se počáteční data přidružují k typu entity jako součást konfigurace modelu. Migrace EF Core pak můžou automaticky vypočítat, jaké operace vložení, aktualizace nebo odstranění je potřeba použít při upgradu databáze na novou verzi modelu.

Jako příklad můžete použít ke konfiguraci počátečních dat pro post v OnModelCreating:

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

Další informace o tomto tématu najdete v části o počátečních datech.

Typy dotazů

Model EF Core teď může obsahovat typy dotazů. Na rozdíl od typů entit nemají typy dotazů klíče definované pro ně a nelze je vložit, odstranit ani aktualizovat (to znamená, že jsou jen pro čtení), ale můžou být vráceny přímo dotazy. Mezi scénáře použití pro typy dotazů patří:

  • Mapování na zobrazení bez primárních klíčů
  • Mapování na tabulky bez primárních klíčů
  • Mapování na dotazy definované v modelu
  • Slouží jako návratový typ pro FromSql() dotazy

Další informace o tomto tématu najdete v části o typech dotazů.

Zahrnout pro odvozené typy

Při zápisu výrazů pro metodu Include bude nyní možné zadat navigační vlastnosti pouze definované u odvozených typů. Pro verzi silného Includetypu podporujeme použití explicitního přetypování nebo operátoru as . Nyní také podporujeme odkazování na názvy navigační vlastnosti definované na odvozených typech v řetězcové verzi 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");

Další informace o tomto tématu najdete v části Zahrnout s odvozenými typy .

Podpora System.Transactions

Přidali jsme možnost pracovat s funkcemi System.Transactions, jako je TransactionScope. To bude fungovat na rozhraní .NET Framework i .NET Core při použití zprostředkovatelů databáze, které ji podporují.

Další informace o tomto tématu najdete v části System.Transactions .

Lepší řazení sloupců při počáteční migraci

Na základě zpětné vazby zákazníků jsme aktualizovali migrace tak, aby původně vygenerovaly sloupce pro tabulky ve stejném pořadí jako vlastnosti deklarované ve třídách. Všimněte si, že EF Core nemůže změnit pořadí při přidání nových členů po počátečním vytvoření tabulky.

Optimalizace korelovaných poddotazů

Vylepšili jsme překlad dotazů, abychom se vyhnuli provádění dotazů SQL "N + 1" v mnoha běžných scénářích, kdy použití navigační vlastnosti v projekci vede k propojení dat z kořenového dotazu s daty z korelovaného poddotazu. Optimalizace vyžaduje ukládání výsledků do vyrovnávací paměti z poddotazů a vyžadujeme, abyste dotaz upravili tak, aby se přihlásil k novému chování.

Například následující dotaz se obvykle přeloží do jednoho dotazu pro zákazníky a navíc N (kde N je počet vrácených zákazníků) samostatných dotazů pro objednávky:

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

ToList() Zahrnutím na správné místo označujete, že ukládání do vyrovnávací paměti je vhodné pro objednávky, které umožňují optimalizaci:

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

Všimněte si, že tento dotaz se přeloží jenom na dva dotazy SQL: jeden pro zákazníky a další dotaz pro objednávky.

Atribut [Vlastněno]

Teď je možné nakonfigurovat vlastněné typy entit jednoduše přidáním poznámek k typu [Owned] a následným ověřením, že je entita vlastníka přidána do modelu:

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

Nástroj příkazového řádku dotnet-ef zahrnutý v sadě .NET Core SDK

Příkazy dotnet-ef jsou nyní součástí sady .NET Core SDK, takže už nebude nutné používat DotNetCliToolReference v projektu, aby bylo možné používat migrace nebo vygenerovat dbContext z existující databáze.

Další podrobnosti o povolení nástrojů pro různé verze sady .NET Core SDK a EF Core najdete v části o instalaci nástrojů příkazového řádku.

Balíček Microsoft.EntityFrameworkCore.Abstractions

Nový balíček obsahuje atributy a rozhraní, které můžete ve svých projektech použít ke zsvětlování funkcí EF Core bez závislosti na EF Core jako celku. Například atribut [Owned] a ILazyLoader rozhraní jsou umístěny zde.

Události změny stavu

Nové Tracked události a StateChanged události ChangeTracker lze použít k zápisu logiky, která reaguje na entity, které zadávají DbContext nebo mění jejich stav.

Nezpracovaný analyzátor parametrů SQL

Součástí EF Core je nový analyzátor kódu, který detekuje potenciálně nebezpečné použití našich nezpracovaných rozhraní API SQL, například FromSql nebo ExecuteSqlCommand. Například u následujícího dotazu se zobrazí upozornění, protože minAge není parametrizován:

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

Kompatibilita zprostředkovatele databáze

Doporučujeme používat EF Core 2.1 s poskytovateli, kteří byli aktualizováni nebo alespoň testováni pro práci s EF Core 2.1.

Tip

Pokud v nových funkcích zjistíte neočekávanou nekompatibilitu nebo nějaký problém nebo pokud k nim máte zpětnou vazbu, nahlašte ho pomocí našeho sledování problémů.