EF Core 2.1 の新機能

EF Core 2.1 には、多数のバグ修正と小規模な機能とパフォーマンスの強化に加えて、いくつかの魅力的な新機能が含まれています。

遅延読み込み

EF Core には、必要に応じてナビゲーション プロパティを読み込むことができるエンティティ クラスを作成するために必要な構成要素が含まれるようになりました。 また、これらの構成要素を利用して、最小限に変更されたエンティティ クラス (仮想ナビゲーション プロパティを持つクラスなど) に基づいて遅延読み込みプロキシ クラスを生成する新しいパッケージ Microsoft.EntityFrameworkCore.Proxies も作成しました。

このトピックの詳細については、遅延読み込み の セクションを参照してください。

エンティティ コンストラクターのパラメーター

遅延読み込みに必要な構成要素の 1 つとして、コンストラクターでパラメーターを受け取るエンティティの作成を有効にしました。 パラメーターを使用して、プロパティ値、遅延読み込みデリゲート、およびサービスを挿入できます。

このトピックの詳細については、 パラメーターを含むエンティティ コンストラクターの セクションを参照してください。

値の変換

これまで、EF Core では、基になるデータベース プロバイダーによってネイティブにサポートされている型のプロパティのみをマップできました。 変換を行わずに、列とプロパティの間で値が前後にコピーされました。 EF Core 2.1 以降では、値変換を適用して、列から取得した値をプロパティに適用する前に変換できます。その逆も可能です。 必要に応じて規則によって適用できる変換と、列とプロパティの間でカスタム変換を登録できる明示的な構成 API があります。 この機能の一部のアプリケーションは次のとおりです。

  • 列挙型を文字列として格納する
  • SQL Server を使用した符号なし整数のマッピング
  • プロパティ値の自動暗号化と暗号化解除

このトピックの詳細については、 値の変換に関する セクションを参照してください。

LINQ GroupBy 変換

バージョン 2.1 より前の EF Core では、GroupBy LINQ 演算子は常にメモリ内で評価されます。 最も一般的なケースでは、SQL GROUP BY 句への変換がサポートされるようになりました。

この例では、さまざまな集計関数を計算するために GroupBy を使用するクエリを示します。

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 変換は次のようになります。

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

データ シード処理

新しいリリースでは、データベースを設定するための初期データを提供できます。 EF6 とは異なり、シード処理データはモデル構成の一部としてエンティティ型に関連付けられます。 その後、EF Core の移行では、データベースを新しいバージョンのモデルにアップグレードするときに適用する必要がある挿入、更新、または削除操作を自動的に計算できます。

たとえば、これを使用して、OnModelCreatingの Post のシード データを構成できます。

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

このトピックの詳細については、データ シード処理 に関する セクションを参照してください。

クエリの種類

EF Core モデルにクエリの種類を含めることができるようになりました。 エンティティ型とは異なり、クエリ型にはキーが定義されておらず、挿入、削除、または更新することはできません (つまり、読み取り専用です)。 クエリの種類の使用シナリオの一部を次に示します。

  • 主キーを使用しないビューへのマッピング
  • 主キーのないテーブルへのマッピング
  • モデルで定義されているクエリへのマッピング
  • FromSql() クエリの戻り値の型として機能する

このトピックの詳細については、 クエリの種類に関する セクションを参照してください。

派生型の Include

Include メソッドの式を記述するときに、派生型でのみ定義されたナビゲーション プロパティを指定できるようになりました。 Include の厳密に型指定されたバージョンについては、明示的なキャストまたは as 演算子を使用してサポートします。 また、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 に関するセクションをご覧ください。

System.Transactions のサポート

TransactionScope などの System.Transactions 機能を操作する機能が追加されました。 これは、それをサポートするデータベース プロバイダーを使用する場合、.NET Framework と .NET Core の両方で機能します。

このトピックの詳細については、System.Transactions の セクションを参照してください。

初期移行での列の順序の改善

お客様からのフィードバックに基づいて、プロパティがクラスで宣言されているのと同じ順序でテーブルの列を最初に生成するように移行が更新されました。 最初のテーブルの作成後に新しいメンバーを追加した場合、EF Core は順序を変更できないことに注意してください。

相関サブクエリの最適化

プロジェクションでナビゲーション プロパティを使用すると、ルート クエリのデータと関連付けられたサブクエリのデータが結合される多くの一般的なシナリオで"N + 1" SQL クエリが実行されないように、クエリ変換が改善されました。 最適化では、サブクエリからの結果をバッファリングする必要があり、新しい動作をオプトインするようにクエリを変更する必要があります。

たとえば、次のクエリは通常、顧客の 1 つのクエリに加えて、注文に対する N ("N" は返された顧客の数) の個別のクエリに変換されます。

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

適切な場所に ToListAsync() を含めることで、バッファリングが Orders に適していることを示し、最適化を有効にします。

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

このクエリは、2 つの SQL クエリ (1 つは Customers 用、次は Orders) にのみ変換されることに注意してください。

[Owned] 属性

を使用して型に注釈を付け、所有者エンティティがモデルに追加されるようにすることで、 所有エンティティ型を構成できるようになりました。

[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-ef

dotnet-ef コマンドは .NET Core SDK に含まれるようになったため、移行を使用したり、既存のデータベースから DbContext をスキャフォールディングしたりするために、プロジェクトで DotNetCliToolReference を使用する必要がなくなりました。

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

Microsoft.EntityFrameworkCore.Abstractions パッケージ

新しいパッケージには、EF Core 全体に依存することなく EF Core 機能を明るくするためにプロジェクトで使用できる属性とインターフェイスが含まれています。 たとえば、[Owned] 属性と ILazyLoader インターフェイスがここに配置されます。

状態変更イベント

Tracked の新しい StateChanged And ChangeTracker イベントを使用して、DbContext に入ったり状態を変更したりするエンティティに反応するロジックを記述できます。

RAW SQL パラメーター アナライザー

FromSqlExecuteSqlCommandなど、未加工の SQL API の安全でない可能性のある使用状況を検出する新しいコード アナライザーが EF Core に含まれています。 たとえば、次のクエリでは、minAge パラメーター化されていないため、警告が表示されます。

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

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

EF Core 2.1 で動作するように更新または少なくともテストされたプロバイダーで EF Core 2.1 を使用することをお勧めします。

ヒント

新しい機能で予期しない互換性や問題が見つかる場合、またはそれらに関するフィードバックがある場合は、問題トラッカー使用して報告してください。