Neue Features in EF Core 2.1New features in EF Core 2.1

Neben zahlreichen Fehlerbehebungen und kleinen Funktions- und Leistungsverbesserungen umfasst EF Core 2.1 einige interessante neue Features:Besides numerous bug fixes and small functional and performance enhancements, EF Core 2.1 includes some compelling new features:

Lazy LoadingLazy loading

EF Core enthält nun die erforderlichen Bausteine für Benutzer, die Entitätsklassen zum bedarfsgesteuerten Laden ihrer Navigationseigenschaften erstellen möchten.EF Core now contains the necessary building blocks for anyone to author entity classes that can load their navigation properties on demand. Wir haben zudem das neue Paket „Microsoft.EntityFrameworkCore.Proxies“ erstellt, das mithilfe dieser Bausteine Proxyklassen zum Lazy Loading auf Grundlage minimal geänderter Entitätsklassen (z.B. Klassen mit virtuellen Navigationseigenschaften) erzeugt.We have also created a new package, Microsoft.EntityFrameworkCore.Proxies, that leverages those building blocks to produce lazy loading proxy classes based on minimally modified entity classes (for example, classes with virtual navigation properties).

Weitere Informationen zu diesem Thema finden Sie im Abschnitt zum Lazy Loading.Read the section on lazy loading for more information about this topic.

Parameter in EntitätskonstruktorenParameters in entity constructors

Als einer der erforderlichen Bausteine zum Lazy Loading haben wir die Erstellung von Entitäten ermöglicht, die Parameter in ihren Konstruktoren akzeptieren.As one of the required building blocks for lazy loading, we enabled the creation of entities that take parameters in their constructors. Sie können mithilfe von Parametern Eigenschaftswerte, Delegaten zum Lazy Loading und Dienste einfügen.You can use parameters to inject property values, lazy loading delegates, and services.

Weitere Informationen zu diesem Thema finden Sie im Abschnitt zum Entitätskonstruktor mit Parametern.Read the section on entity constructor with parameters for more information about this topic.

WertkonvertierungenValue conversions

Bislang konnte EF Core nur Eigenschaften von Typen zuordnen, die vom zugrunde liegenden Datenbankanbieter nativ unterstützt wurden.Until now, EF Core could only map properties of types natively supported by the underlying database provider. Werte wurden zwischen Spalten und Eigenschaften ohne jegliche Transformation hin und her kopiert.Values were copied back and forth between columns and properties without any transformation. Ab EF Core 2.1 können Wertkonvertierungen angewendet werden, um die aus Spalten abgerufenen Werte vor der Anwendung auf Eigenschaften zu transformieren (und umgekehrt).Starting with EF Core 2.1, value conversions can be applied to transform the values obtained from columns before they are applied to properties, and vice versa. Wir verfügen über eine Reihe von Konvertierungen, die der Konvention entsprechend bei Bedarf angewendet werden können, sowie über eine explizite Konfigurations-API, die die Registrierung von benutzerdefinierten Konvertierungen zwischen Spalten und Eigenschaften ermöglicht.We have a number of conversions that can be applied by convention as necessary, as well as an explicit configuration API that allows registering custom conversions between columns and properties. Einige Anwendungsgebiete für dieses Feature sind z.B. Folgende:Some of the application of this feature are:

  • Speichern von Enumerationen als ZeichenfolgenStoring enums as strings
  • Zuordnen von ganzen Zahlen ohne Vorzeichen mit SQL ServerMapping unsigned integers with SQL Server
  • Automatische Ver- und Entschlüsselung von EigenschaftswertenAutomatic encryption and decryption of property values

Weitere Informationen zu diesem Thema finden Sie im Abschnitt zu Wertkonvertierungen.Read the section on value conversions for more information about this topic.

LINQ-GroupBy-ÜbersetzungLINQ GroupBy translation

Vor Version 2.1 wurde der LINQ-Operator „GroupBy“ in EF Core immer im Arbeitsspeicher ausgewertet.Before version 2.1, in EF Core the GroupBy LINQ operator would always be evaluated in memory. Nun bieten wir in den meisten Fällen Unterstützung für dessen Übersetzung in die GROUP BY-SQL-Klausel.We now support translating it to the SQL GROUP BY clause in most common cases.

Dieses Beispiel zeigt eine Abfrage mit GroupBy zum Berechnen verschiedener Aggregatfunktionen:This example shows a query with GroupBy used to compute various aggregate functions:

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

Die entsprechende SQL-Übersetzung sieht wie folgt aus:The corresponding SQL translation looks like this:

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

DatenseedingData Seeding

Mit dem neuen Release ist es möglich, die ursprünglichen Daten zum Auffüllen einer Datenbank anzugeben.With the new release it will be possible to provide initial data to populate a database. Im Gegensatz zu EF 6 wird das Datenseeding mit einem Entitätstyp als Teil der Modellkonfiguration verknüpft.Unlike in EF6, seeding data is associated to an entity type as part of the model configuration. EF Core-Migrationen können dann automatisch berechnen, welche Einfüge-, Aktualisierungs- oder Löschvorgänge beim Durchführen eines Upgrades für die Datenbank auf eine neue Modellversion angewendet werden müssen.Then EF Core migrations can automatically compute what insert, update or delete operations need to be applied when upgrading the database to a new version of the model.

Beispielsweise können Sie damit Seeddaten für ein Post-Element in OnModelCreating konfigurieren:As an example, you can use this to configure seed data for a Post in OnModelCreating:

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

Weitere Informationen zu diesem Thema finden Sie im Abschnitt zum Datenseeding.Read the section on data seeding for more information about this topic.

AbfragetypenQuery types

Ein EF Core-Modell kann nun Abfragetypen einschließen.An EF Core model can now include query types. Im Gegensatz zu Entitätstypen werden für Abfragetypen keine Schlüssel definiert, und sie können nicht eingefügt, gelöscht oder aktualisiert werden (d.h., sie sind schreibgeschützt). Sie können jedoch direkt von Abfragen zurückgegeben werden.Unlike entity types, query types do not have keys defined on them and cannot be inserted, deleted or updated (that is, they are read-only), but they can be returned directly by queries. Einige Verwendungsszenarien für Abfragetypen sind z.B. Folgende:Some of the usage scenarios for query types are:

  • Zuordnen mit Ansichten ohne PrimärschlüsselMapping to views without primary keys
  • Zuordnen mit Tabellen ohne PrimärschlüsselMapping to tables without primary keys
  • Zuordnen mit im Modell definierten AbfragenMapping to queries defined in the model
  • Verwendung als Rückgabetyp für FromSql()-AbfragenServing as the return type for FromSql() queries

Weitere Informationen zu diesem Thema finden Sie im Abschnitt zu Abfragetypen.Read the section on query types for more information about this topic.

Einschließen für abgeleitete TypenInclude for derived types

Nun ist es möglich, beim Schreiben von Ausdrücken für die Include-Methode nur für abgeleitete Typen definierte Navigationseigenschaften anzugeben.It will be now possible to specify navigation properties only defined on derived types when writing expressions for the Include method. Für die stark typisierte Include-Version unterstützen wir entweder die Verwendung einer expliziten Umwandlung oder des as-Operators.For the strongly typed version of Include, we support using either an explicit cast or the as operator. Nun bieten wir auch Unterstützung für den Verweis der für abgeleitete Typen definierten Namen der Navigationseigenschaften in der Zeichenfolgenversion Include:We also now support referencing the names of navigation property defined on derived types in the string version of 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");

Weitere Informationen zu diesem Thema finden Sie im Abschnitt zum Einschließen mit abgeleiteten Typen.Read the section on Include with derived types for more information about this topic.

System.Transactions-UnterstützungSystem.Transactions support

Wir haben die Möglichkeit zum Arbeiten mit System.Transactions-Features wie TransactionScope hinzugefügt.We have added the ability to work with System.Transactions features such as TransactionScope. Dieses funktioniert in .NET Framework und .NET Core bei der Verwendung von Datenbankanbietern, die Unterstützung hierfür bieten.This will work on both .NET Framework and .NET Core when using database providers that support it.

Weitere Informationen zu diesem Thema finden Sie im Abschnitt zu System.Transactions.Read the section on System.Transactions for more information about this topic.

Bessere Spaltensortierung bei der anfänglichen MigrationBetter column ordering in initial migration

Basierend auf dem Feedback von Kunden haben wir Migrationen dahingehend aktualisiert, dass Spalten für Tabellen zunächst in der gleichen Reihenfolge wie die Deklaration von Eigenschaften in Klassen generiert werden.Based on customer feedback, we have updated migrations to initially generate columns for tables in the same order as properties are declared in classes. Beachten Sie, dass EF Core nicht die Reihenfolge ändern kann, wenn nach der Erstellung der ersten Tabelle neue Member hinzugefügt werden.Note that EF Core cannot change order when new members are added after the initial table creation.

Optimierung von korrelierten UnterabfragenOptimization of correlated subqueries

Wir haben unsere Abfrageübersetzung dahingehend verbessert, dass die Ausführung von „N+1“-SQL-Abfragen in vielen gängigen Szenarien verhindert wird, in denen die Verwendung einer Navigationseigenschaft in der Projektion zum Verknüpfen von Daten aus der Stammabfrage mit Daten aus einer korrelierten Unterabfrage führt.We have improved our query translation to avoid executing "N + 1" SQL queries in many common scenarios in which the usage of a navigation property in the projection leads to joining data from the root query with data from a correlated subquery. Für die Optimierung ist das Puffern der Ergebnisse aus der Unterabfrage erforderlich. Zudem ist es erforderlich, die Abfrage zum Auswählen des neuen Verhaltens zu ändern.The optimization requires buffering the results from the subquery, and we require that you modify the query to opt-in the new behavior.

Die folgende Abfrage wird z.B. normalerweise in eine Abfrage für Kunden plus N separate Abfragen für Aufträge übersetzt („N“ steht hierbei für die Anzahl der zurückgegebenen Kunden):As an example, the following query normally gets translated into one query for Customers, plus N (where "N" is the number of customers returned) separate queries for Orders:

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

Durch Einschließen von ToList() an der richtigen Stelle geben Sie an, dass eine Pufferung für die Aufträge, die die Optimierung ermöglichen, angemessen ist:By including ToList() in the right place, you indicate that buffering is appropriate for the Orders, which enable the optimization:

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

Beachten Sie, dass diese Abfrage nur in zwei SQL-Abfragen übersetzt wird: Eine für Kunden, die andere für Aufträge.Note that this query will be translated to only two SQL queries: One for Customers and the next one for Orders.

Das [Owned]-Attribut[Owned] attribute

Nun können Entitätstypen im Besitz konfiguriert werden, indem einfach der Typ mit [Owned] kommentiert und dann sichergestellt wird, dass die Besitzerentität zum Modell hinzugefügt wird:It is now possible to configure owned entity types by simply annotating the type with [Owned] and then making sure the owner entity is added to the model:

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

dotnet-ef-Befehle des Befehlszeilentools im .NET Core SDKCommand-line tool dotnet-ef included in .NET Core SDK

Die dotnet-ef-Befehle sind nun im .NET Core SDK enthalten. Deshalb ist es nicht mehr erforderlich, „DotNetCliToolReference“ für Migrationen oder den DbContext-Gerüstbau aus einer vorhandenen Datenbank im Projekt zu verwenden.The dotnet-ef commands are now part of the .NET Core SDK, therefore it will no longer be necessary to use DotNetCliToolReference in the project to be able to use migrations or to scaffold a DbContext from an existing database.

Weitere Details zum Aktivieren der Befehlszeilentools für verschiedene Versionen des .NET Core SDK und von EF Core finden Sie im Abschnitt zur Installation der Tools.See the section on installing the tools for more details on how to enable command line tools for different versions of the .NET Core SDK and EF Core.

Paket „Microsoft.EntityFrameworkCore.Abstractions“Microsoft.EntityFrameworkCore.Abstractions package

Das neue Paket enthält Attribute und Schnittstellen, mit denen Sie EF Core-Features in Ihren Projekten aktivieren können, ohne eine Abhängigkeit von EF Core insgesamt einzugehen.The new package contains attributes and interfaces that you can use in your projects to light up EF Core features without taking a dependency on EF Core as a whole. Das [Owned]-Attribut und die ILazyLoader-Schnittstelle sind beispielsweise enthalten.For example, the [Owned] attribute and the ILazyLoader interface are located here.

ZustandsänderungsereignisseState change events

Die neuen Ereignisse Tracked und StateChanged für ChangeTracker können verwendet werden, um Logik zur Reaktion auf Entitäten zu schreiben, die in den DbContext wechseln oder ihren Zustand ändern.New Tracked And StateChanged events on ChangeTracker can be used to write logic that reacts to entities entering the DbContext or changing their state.

Raw-SQL-ParameteranalyseRaw SQL parameter analyzer

EF Core umfasst ein neues Tool für die Codeanalyse, mit der potenziell unsichere Verwendungen unserer Raw-SQL-APIs erkannt werden, z.B. FromSql oder ExecuteSqlCommand.A new code analyzer is included with EF Core that detects potentially unsafe usages of our raw-SQL APIs, like FromSql or ExecuteSqlCommand. Für die folgende Abfrage wird beispielweise eine Warnung angezeigt, weil minAge nicht parametrisiert ist:For example, for the following query, you will see a warning because minAge is not parameterized:

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

Kompatibilität mit DatenbankanbieternDatabase provider compatibility

Es wird empfohlen, EF Core 2.1 mit Anbietern zu verwenden, die ein Update auf EF Core 2.1 durchgeführt oder EF Core 2.1 bereits getestet haben.It is recommended that you use EF Core 2.1 with providers that have been updated or at least tested to work with EF Core 2.1.

Tipp

Falls unerwarteterweise keine Kompatibilität besteht oder Probleme mit den neuen Features auftreten, oder falls Sie uns Ihre Feedback mitteilen möchten, melden Sie uns dies über unsere Problemverfolgung.If you find any unexpected incompatibility or any issue in the new features, or if you have feedback on them, please report it using our issue tracker.