クエリのしくみHow Queries Work

Entity Framework Core では統合言語クエリ (LINQ) を使用し、データベースにデータを問い合わせます。Entity Framework Core uses Language Integrate Query (LINQ) to query data from the database. LINQ では C# (あるいは自分で選んだ .NET 言語) を使用し、派生コンテキストとエンティティ クラスに基づいて、厳密に型指定されたクエリを記述できます。LINQ allows you to use C# (or your .NET language of choice) to write strongly typed queries based on your derived context and entity classes.

クエリの全体像The life of a query

各クエリが通過するプロセスの高次元での概要を次に示します。The following is a high level overview of the process each query goes through.

  1. LINQ クエリは、データベース プロバイダーで処理するために用意された表現をビルドするために、Entity Framework Core によって処理されます。The LINQ query is processed by Entity Framework Core to build a representation that is ready to be processed by the database provider
    1. クエリが実行されるたびにこの処理が実行される必要がないように、結果はキャッシュされます。The result is cached so that this processing does not need to be done every time the query is executed
  2. 結果が、データベース プロバイダーに渡されます。The result is passed to the database provider
    1. データベース プロバイダーは、クエリのどの部分がデータベースで評価できるかを識別します。The database provider identifies which parts of the query can be evaluated in the database
    2. クエリのこれらの部分は、データベース固有のクエリ言語 (リレーショナル データベースの SQL など) に変換されます。These parts of the query are translated to database specific query language (e.g. SQL for a relational database)
    3. 1 つまたは複数のクエリがデータべースに送信され、結果セットが返されます (結果は、エンティティ インスタンスではなく、データベースからの値です)。One or more queries are sent to the database and the result set returned (results are values from the database, not entity instances)
  3. 結果セット内の各項目で、For each item in the result set
    1. これが追跡クエリの場合、EF では、データがコンテキスト インスタンスの変更追跡に既にあるエンティティを表しているかどうかをチェックします。If this is a tracking query, EF checks if the data represents an entity already in the change tracker for the context instance
      • 既にある場合、既存のエンティティが返されます。If so, the existing entity is returned
      • ない場合、新しいエンティティが作成され、変更追跡が設定されて、新しいエンティティが返されます。If not, a new entity is created, change tracking is setup, and the new entity is returned
    2. これが追跡なしのクエリの場合、EF では、データがこのクエリの結果セットに既にあるエンティティを表しているかどうかをチェックします。If this is a no-tracking query, EF checks if the data represents an entity already in the result set for this query
      • 既にある場合、既存のエンティティが返されます(1)If so, the existing entity is returned (1)
      • ない場合、新しいエンティティが作成されて、返されます。If not, a new entity is created and returned

(1) 既に返されたエンティティの追跡を継続するために、追跡なしクエリでは弱参照を使用します。(1) No tracking queries use weak references to keep track of entities that have already been returned. 同じ ID の前の結果が範囲外になっている場合は、ガベージ コレクションが実行され、新しいエンティティ インスタンスを取得できます。If a previous result with the same identity goes out of scope, and garbage collection runs, you may get a new entity instance.

クエリの実行時When queries are executed

LINQ 演算子を呼び出すと、単純にクエリのメモリ内表現がビルドされます。When you call LINQ operators, you are simply building up an in-memory representation of the query. クエリは、結果が使用されるときにデータベースに送信されるだけです。The query is only sent to the database when the results are consumed.

クエリでの結果がデータベースに送信される最も一般的な操作は、次のとおりです。The most common operations that result in the query being sent to the database are:

  • for ループ内で結果を反復処理するIterating the results in a for loop
  • ToListToArraySingleCount などの演算子を使用するUsing an operator such as ToList, ToArray, Single, Count
  • クエリの結果を UI にデータバインドするDatabinding the results of a query to a UI

警告

ユーザー入力を常に検証する: EF が SQL インジェクション攻撃からの保護を提供している間は、一般的な入力の検証はまったく行われません。Always validate user input: While EF does provide protection from SQL injection attacks, it does not do any general validation of input. そのため、値が API に渡される、LINQ クエリで使用される、エンティティ プロパティに割り当てられるなどの場合に、それらの値が信頼されていないソースに由来していると、アプリケーションの要件ごとに適切な検証が実行される必要があります。Therefore if values being passed to APIs, used in LINQ queries, assigned to entity properties, etc., come from an untrusted source then appropriate validation, per your application requirements, should be performed. これには、動的にクエリを構築する際に使用されるユーザー入力も含まれます。This includes any user input used to dynamically construct queries. LINQ を使用している場合であっても、式をビルドするためのユーザー入力を許可しているなら、目的の式だけは構築できることを確認する必要があります。Even when using LINQ, if you are accepting user input to build expressions you need to make sure than only intended expressions can be constructed.