EntityFramework Coreでこの警告が表示されるのはなぜですか?
私はすでにMSSQL日付ベースを大文字と小文字を区別するように設定しています。
Latin1_General_100_CS_AS
var test = await _context.Students
.FirstOrDefaultAsync(m => m.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase));
Microsoft.EntityFrameworkCore.Query:Warning:LINQ式 'where [m] .LastName.Equals( "ALEXANDER"、InvariantCultureIgnoreCase)'は翻訳できず、ローカルで評価されます。
IEnumerable
とIqueryable
の違いに注意する必要があります。
IEnumerable
オブジェクトは、一連のオブジェクトを表します。これは、このシーケンスを列挙するためにすべてを保持します。シーケンスの最初の要素を要求できます。要素を取得したら、次の要素がある限り、次の要素を要求できます。
IQueryable
オブジェクトはIEnumerableのように見えますが、列挙可能なシーケンスを表すのではなく、IEnumerableシーケンスを取得する可能性を表しています。
IQueryableオブジェクトはExpression
とProvider
を保持します。 Expression
は、照会する必要があるものを表す一般的な説明です。 Provider
は、クエリを実行するユーザー(通常はデータベース管理システム)と、このDBMSとの通信に使用される言語(通常はSQL)を認識しています。
GetEnumerator
とMoveNext
を明示的に使用するか、foreach、ToList、Max、FirstOrDefaultなどを呼び出して暗黙的にIQueryableの列挙を開始すると、GetEnumeratorとMoveNextの呼び出しの内部で、式はプロバイダーに送信されます。プロバイダーはそれをSQLに変換し、DBMSからデータをフェッチします。フェッチされたデータはIEnumerableとして返され、GetEnumeratorおよびMoveNextが呼び出されます。
したがって、GetEnumeratorとMoveNextを呼び出す前にクエリは実行されません。
これは私の質問と何をしているのですか?
エンティティフレームワークは、クラスとメソッドを、認識しているSQLにのみ変換できます。 Entity Frameworkはあなた自身の機能を知りません。実際、エンティティフレームワークでサポートされていないLINQ関数がいくつかあります。 サポートされているおよびサポートされていないLINQメソッドを参照してください
サポートされていないメソッドの1つはString.Equals(string, StringComparison)
です。この関数を使用すると、コンパイラーは文句を言わず、実行時にこのエラーが表示されます。これは、関数が呼び出される前に、最初にデータがフェッチされることを示しています。これは非効率的な動作につながる可能性があります。
あなたのLINQステートメントは(問題の一部ではなく、非同期待機を除外して)等しいです
var test = dbContext.Students
.Where(student => student.LastName.Equals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase))
.FirstOrDefault();
Equalsは使用できないため、警告はWhereが実行される前にデータがローカルにフェッチされることを示しています。したがって、Whereを通過しないいくつかのアイテムがDBMSからローカルプロセスに転送される可能性があります。
データベースで大文字と小文字の区別を無視できる場合は、コードを次のように変更することを検討してください。
var test = dbContext.Students
.Where(student => student.LastName == "ALEXANDER")
.FirstOrDefault();
これにより、次のようなSQLステートメントが生成されます。
SELECT TOP 1 * from myDatabase.Students where LastName = "ALEXANDER"
(これが正しいSQLであるかどうかはわかりません。エンティティフレームワークを使用しているので、私のSQLは少し錆びています。Gistが表示されると思います)
EntityFrameworkはEquals("ALEXANDER", StringComparison.InvariantCultureIgnoreCase)
をSQLに変換できないため、代わりにすべてのStudentテーブルをメモリにロードし、等式を満たす最初のエントリを検索します。