質問: await Task.Run(() => ctx.Contracts.Where(predicate).FirstOrDefault()); return entities; } ``` 私はこれに関する2つの質問があります: 1. 述語を渡すときに`FirstOrDefaultAsync()`メソッドにアクセスできないのはなぜですか? 2. `await Task.Run(synchronousMethod)`が`FirstOrDefaultAsync()`呼び出しと同じ動作をするのを`await Task.Run(synchronousMethod)`いる私の解決策はありますか?
回答: `FirstOrDefaultAsync`は、 `IQueryable`拡張メソッドとして定義されています。 `ctx.MyEntities.Where(e => e.Id == 1)`は、 `IQueryable`返します。 `ctx.MyEntities.Where(predicate)`は、 `Queryable.Where`ではなく、 `Enumerable.Where`拡張メソッドを呼び出すため、 `IEnumerable`返し`Queryable.Where` 。 それを機能させるには、 `predicate`を`Func`から`Expression>`ます。これは、 `predicate`がもはやあなたが望む結果を与える関数ではなく、その関数の説明で、Entity FrameworkがSQLに変換できることを意味します。 また、タスク内で`Func`を使用しても、同じ動作は行われません。これは、フィルタリングを行わずにdbサーバからローをロードし、一致が見つかるまでdbクライアントのすべてを評価します。それは多くのオーバーヘッドを追加します。