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 nyní obsahuje potřebné stavební bloky pro vytvoření tříd entit, které dokážou na vyžádání načíst své navigační vlastnosti. 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).

Pro další informace o tomto tématu si přečtěte část o lenivém 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é ve svých 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 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];

Nasazení počátečních 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.

Můžete to například použít ke konfiguraci počátečních dat pro post v OnModelCreating:

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

Pro více informací o tomto tématu si přečtěte část o seedování dat.

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

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 teď bude možné zadat navigační vlastnosti pouze definované u odvozených typů. Verzi silného typu Includepodporujeme použití explicitního přetypování nebo operátoru as. Nyní také podporujeme odkazování na názvy navigačních vlastností, které jsou definovány na odvozených typech, ve formátu řetězce 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ů poddotazů do vyrovnávací paměti a požadujeme, abyste dotaz upravili tak, aby povolil nové 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));

Zahrnutím ToListAsync() na správném místě označíte, ž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 vlastnictví

Teď je možné nakonfigurovat vlastněné typy entit jednoduše anotací typu pomocí [Owned] a pak zajistit, aby byla 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 teď součástí sady .NET Core SDK, a proto už nebude nutné v projektu používat DotNetCliToolReference, aby bylo možné používat migrace nebo vygenerování dbContext z existující databáze.

Podívejte se do části o instalaci nástrojů pro více podrobností o tom, jak povolit nástroje příkazového řádku pro odlišné verze sady .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 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é události Tracked a StateChanged na 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 rozhraní API raw-SQL, jako jsou 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.

Spropitné

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