EF Core 2.1 の新機能New features in EF Core 2.1

多数のバグ修正と小さな機能およびパフォーマンスの強化だけでなく、EF Core 2.1 にはいくつかの魅力的な新機能が含まれています。Besides numerous bug fixes and small functional and performance enhancements, EF Core 2.1 includes some compelling new features:

遅延読み込みLazy loading

EF Core に、すべてのユーザーが自身のナビゲーション プロパティを必要なときに読み込むことができるエンティティ クラスを作成するために必要なビルド ブロックが含まれるようになりました。EF Core now contains the necessary building blocks for anyone to author entity classes that can load their navigation properties on demand. また、これらのビルド ブロックを利用して、最小限の変更を行ったエンティティ クラス (仮想ナビゲーション プロパティが指定されたクラスなど) に基づいて遅延読み込みプロキシ クラスを生成する、新しいパッケージ Microsoft.EntityFrameworkCore.Proxies も作成しました。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).

このトピックの詳細については、遅延読み込みのセクションをご覧ください。Read the section on lazy loading for more information about this topic.

エンティティ コンストラクターのパラメーターParameters in entity constructors

遅延読み込みに必要なビルド ブロックの 1 つとして、コンストラクターでパラメーターを受け取るエンティティを作成できるようにしました。As one of the required building blocks for lazy loading, we enabled the creation of entities that take parameters in their constructors. パラメーターを使用して、プロパティ値、遅延読み込みデリゲート、およびサービスを挿入することができます。You can use parameters to inject property values, lazy loading delegates, and services.

このトピックの詳細については、パラメーターが指定されたエンティティ コンストラクターに関するセクションをご覧ください。Read the section on entity constructor with parameters for more information about this topic.

値変換Value conversions

これまで、EF Core では、基になるデータベース プロバイダーでネイティブにサポートされる型のプロパティしかマップできませんでした。Until now, EF Core could only map properties of types natively supported by the underlying database provider. 値は、変換されずに列とプロパティの間で相互にコピーされていました。Values were copied back and forth between columns and properties without any transformation. EF Core 2.1 以降では、列から取得された値を、値変換を適用して変換してから、プロパティに適用することができます。その逆も可能です。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. 必要に応じて、規則によって適用できる多くの変換に加え、列とプロパティ間のカスタム変換を登録できるようにする明示的な構成 API もあります。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. この機能の用途をいくつか次に示します。Some of the application of this feature are:

  • 列挙型を文字列として格納するStoring enums as strings
  • 符号なし整数と SQL Server とのマッピングMapping unsigned integers with SQL Server
  • プロパティ値の自動での暗号化と復号化Automatic encryption and decryption of property values

このトピックの詳細については、値変換のセクションをご覧ください。Read the section on value conversions for more information about this topic.

LINQ GroupBy 変換LINQ GroupBy translation

EF Core 2.1 より前のバージョンでは、GroupBy LINQ 演算子は常にメモリ内で評価されます。Before version 2.1, in EF Core the GroupBy LINQ operator would always be evaluated in memory. これを最も一般的なケースの SQL GROUP BY 句に変換することがサポートされるようになりました。We now support translating it to the SQL GROUP BY clause in most common cases.

この例では、さまざまな集計関数の計算に使用される GroupBy を使用したクエリを示しています。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)
        });

対応する SQL 変換は、次のようになります。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];

データのシード処理Data Seeding

新しいリリースでは、データベースに入力する初期データを提供することができます。With the new release it will be possible to provide initial data to populate a database. EF6 とは異なり、データのシード処理がモデルの構成の一部としてエンティティ型に関連付けられています。Unlike in EF6, seeding data is associated to an entity type as part of the model configuration. EF Core の移行では、データベースをモデルの新しいバージョンにアップグレードするときに、挿入、更新、または削除のどの操作を適用する必要があるかを自動的に計算できます。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.

次の例に示すように、これを使用して OnModelCreating の Post にシード データを構成できます。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!" });

このトピックの詳細については、データのシード処理に関するセクションをご覧ください。Read the section on data seeding for more information about this topic.

クエリ型Query types

EF Core モデルにクエリ型を含めることができるようになりました。An EF Core model can now include query types. エンティティ型とは異なり、クエリ型には定義されたキーがないため、クエリ型を挿入、削除または更新することができません (つまり、読み取り専用です)。ただし、クエリによって直接返すことができます。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. クエリ型の使用シナリオをいくつか次に示します。Some of the usage scenarios for query types are:

  • 主キーを使用しないビューへのマッピングMapping to views without primary keys
  • 主キーを使用しないテーブルへのマッピングMapping to tables without primary keys
  • モデルで定義されているクエリへのマッピングMapping to queries defined in the model
  • FromSql() クエリの戻り値の型として機能Serving as the return type for FromSql() queries

このトピックの詳細については、クエリ型に関するセクションをご覧ください。Read the section on query types for more information about this topic.

派生型の IncludeInclude for derived types

Include メソッドの式を記述する際に、派生型でのみ定義されているナビゲーション プロパティを指定できるようになりました。It will be now possible to specify navigation properties only defined on derived types when writing expressions for the Include method. Include の厳密に型指定されたバージョンについては、明示的なキャストまたは as 演算子を使用してサポートします。For the strongly typed version of Include, we support using either an explicit cast or the as operator. また、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");

このトピックの詳細については、派生型を使用した Include に関するセクションをご覧ください。Read the section on Include with derived types for more information about this topic.

System.Transactions のサポートSystem.Transactions support

TransactionScope などの System.Transactions 機能が使用できるようになりました。We have added the ability to work with System.Transactions features such as TransactionScope. これは、この機能をサポートするデータベース プロバイダーを使用する場合、.NET Framework と .NET Core の両方で機能します。This will work on both .NET Framework and .NET Core when using database providers that support it.

このトピックの詳細については、System.Transactions に関するセクションをご覧ください。Read the section on System.Transactions for more information about this topic.

最初の移行での列の順序付けの改善Better column ordering in initial migration

お客様のフィードバックに基づき、移行で最初に生成されるテーブルの列を、クラスで宣言されているプロパティと同じ順序になるように更新しました。Based on customer feedback, we have updated migrations to initially generate columns for tables in the same order as properties are declared in classes. EF Core では、最初にテーブルが作成されると、その後で新しいメンバーを追加するときに順序を変更できないことに注意してください。Note that EF Core cannot change order when new members are added after the initial table creation.

相関サブクエリの最適化Optimization of correlated subqueries

プロジェクションでナビゲーション プロパティを使用して、ルート クエリからのデータと相関サブクエリからのデータが結合される多くの一般的なシナリオで、"N + 1" SQL クエリの実行を回避するようにクエリ変換を改善しました。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. 最適化には、サブクエリからの結果のバッファリングが必要なため、新しい動作を受け入れるようにクエリを変更する必要があります。The optimization requires buffering the results from the subquery, and we require that you modify the query to opt-in the new behavior.

例として、次のクエリは、通常、Customers (顧客) の 1 つのクエリに加え、Orders の N 個 ("N" は返された顧客の数) の個別のクエリに変換されます。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));

適切な場所に ToList() を含めることで、最適化を有効にするバッファリングが Orders に適していることを示します。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());

このクエリは、Customers と Orders の 2 つの SQL クエリにのみ変換されることに注意してください。Note that this query will be translated to only two SQL queries: One for Customers and the next one for Orders.

[Owned] 属性[Owned] attribute

[Owned] で型に注釈を付けるだけで、所有エンティティ型を構成して、所有者エンティティをモデルに確実に追加できるようになりました。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; }
}

.NET Core SDK に含まれるコマンド ライン ツール dotnet-efCommand-line tool dotnet-ef included in .NET Core SDK

dotnet-ef コマンドは .NET Core SDK の一部になりました。したがって、移行を使用したり、既存のデータベースから DbContext をスキャフォールディングしたりするために、プロジェクトで DotNetCliToolReference を利用する必要がなくなります。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.

さまざまなバージョンの .NET Core SDK と EF Core でコマンド ライン ツールを有効にする方法の詳細については、「ツールのインストール」のセクションを参照してください。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.

Microsoft.EntityFrameworkCore.Abstractions パッケージMicrosoft.EntityFrameworkCore.Abstractions package

この新しいパッケージに含まれる属性とインターフェイスをプロジェクトで使用すると、EF コアの依存関係全体を取得しなくても、EF Core の機能を使用できます。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. たとえば、[Owned] 属性と ILazyLoader インターフェイスはここにあります。For example, the [Owned] attribute and the ILazyLoader interface are located here.

状態変更イベントState change events

ChangeTracker の新しい Tracked および StateChanged イベントを使用すると、エンティティの DbContext への移行またはその状態の変化に対応するロジックを記述することができます。New Tracked And StateChanged events on ChangeTracker can be used to write logic that reacts to entities entering the DbContext or changing their state.

生 SQL パラメーター アナライザーRaw SQL parameter analyzer

EF Core に組み込まれた新しいコード アナライザーは、FromSqlExecuteSqlCommand などの生 SQL API の安全ではない可能性がある使用法を検出します。A new code analyzer is included with EF Core that detects potentially unsafe usages of our raw-SQL APIs, like FromSql or ExecuteSqlCommand. たとえば次のクエリでは、minAge がパラメーター化されていないため、警告が発生します。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);

データベース プロバイダーの互換性Database provider compatibility

EF Core 2.1 を操作する場合は、更新済みであるか、少なくともテスト済みであるプロバイダーで EF Core 2.1 を使用することをお勧めします。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.

ヒント

予期しない非互換性や新機能で何らかの問題が見つかった場合、またはそれらに対するフィードバックがある場合は、問題の追跡ツールを使用して報告してください。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.