Nové funkce ve EF Core 2.1

Kromě řady oprav chyb a malých vylepšení funkčnosti a výkonu obsahuje EF Core 2.1 některé působivé nové funkce:

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

EF Core teď obsahuje stavební bloky potřebné pro každého, kdo může 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ý využívá tyto stavební bloky k vytvoření opožděného načítání proxy tříd založených na minimálně upravených třídách entit (například tříd s vlastnostmi virtuální navigace).

Další informace o tomto tématu najdete v části 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é převezměte parametry v jejich konstruktorech. Pomocí parametrů můžete vkládat hodnoty vlastností, delegáty opožděné načítání a služby.

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

Převody hodnot

Až dosud EF Core mapovat pouze vlastnosti typů nativně podporovaných podkladovým poskytovatelem databáze. Hodnoty se zkopíroval tam a 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řed jejich použitím na vlastnosti a naopak. Máme řadu převodů, které je možné podle konvence podle potřeby použít, a také rozhraní API pro explicitní konfiguraci, které umožňuje registraci vlastních převodů mezi sloupci a vlastnostmi. Tady jsou některé z aplikací této funkce:

  • Ukládání výčtů jako řetězců
  • Mapování celých čísel bez znaménka pomocí SQL Server
  • 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 EF Core operátor GroupBy LINQ vždy vyhodnocen v paměti. Ve většině běžných případů teď podporujeme překlad SQL klauzuli GROUP BY.

Tento příklad ukazuje dotaz s groupBy, který se používá 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á takhle:

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é zadat počáteční data pro naplnění databáze. Na rozdíl od EF6 je předsudky dat přidružené k typu entity v rámci konfigurace modelu. Potom EF Core migrace 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 dat předávkovaných dat pro příspěvek v OnModelCreating :

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

Další informace o tomto tématu najdete v části o předvysídání dat.

Typy dotazů

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

  • 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 FromSql() pro dotazy.

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

Zahrnutí pro odvozené typy

Při psaní výrazů pro metodu teď bude možné určit navigační vlastnosti definované pouze u odvozených Include typů. Pro verzi silného typu Include podporujeme použití explicitního přetypování nebo as operátoru . Nyní také podporujeme odkazování na názvy navigačních vlastností definovaných u odvozených typů 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 Zahrnutí s odvozenými typy.

Podpora System.Transactions

Přidali jsme možnost pracovat s funkcemi System.Transactions, jako je TransactionScope. To bude fungovat na obou .NET Framework i .NET Core při použití zprostředkovatelů databáze, kteří 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 od zákazníků jsme aktualizovali migrace tak, aby se zpočátku generují sloupce pro tabulky ve stejném pořadí jako vlastnosti deklarované ve třídách. Mějte na EF Core, že při přidání nových členů po počátečním vytvoření tabulky není možné změnit pořadí.

Optimalizace korelovaných poddotazů

Vylepšili jsme překlad dotazů, aby se zabránilo spouštění dotazů N + 1 SQL v mnoha běžných scénářích, kdy použití navigační vlastnosti v projekci vede k spojování dat z kořenového dotazu s daty z korelovaného poddotazu. Optimalizace vyžaduje ukládání výsledků z poddotazu do vyrovnávací paměti a vyžadujeme, abyste tento dotaz upravovat, abyste se mohli rozhodnout pro nové chování.

Například následující dotaz se obvykle přeloží do jednoho dotazu pro zákazníky a 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));

Zahrnutím na správné místo označíte, že ukládání do vyrovnávací paměti je ToList() 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ží pouze na dva SQL dotazy: jeden pro zákazníky a druhý pro Orders.

Atribut [Owned]

Typy vlastněných entit je teď možné nakonfigurovat jednoduše tak, že k typu přidáte poznámku a pak se ověřením, že je do modelu přidaná entita vlastníka:

[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 .NET Core SDK

Příkazy dotnet-ef jsou teď součástí .NET Core SDK, a proto už nebude nutné používat DotNetCliToolReference v projektu, abyste mohli používat migrace nebo vylepšovat DbContext z existující databáze.

Další podrobnosti o tom, jak povolit nástroje příkazového řádku pro různé verze nástrojů příkazového řádku, najdete v části .NET Core SDK a EF Core.

Balíček Microsoft.EntityFrameworkCore.Abstractions

Nový balíček obsahuje atributy a rozhraní, které můžete ve svých projektech použít k EF Core funkcí bez závislosti na EF Core jako celku. Najdete tady například atribut [Owned] (Vlastněné) a rozhraní ILazyLoader.

Události změny stavu

Události New A v systému lze použít k zápisu logiky, která reaguje na entity, které vstupují TrackedStateChanged do ChangeTracker dbContext nebo mění jejich stav.

Analyzátor SQL nezpracovaných parametrů

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

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

Kompatibilita poskytovatele databáze

Doporučujeme používat verzi EF Core 2.1 s poskytovateli, kteří byli aktualizováni nebo alespoň otestovali, aby fungovali s EF Core 2.1.

Tip

Pokud v nových funkcích zjistíte nečekanou nekompatibilitu nebo nějaký problém nebo pokud k nim máte zpětnou vazbu, nahlaste ji pomocí našeho sledování problémů.