コードインスペクション: 「IQueryable」が意図せず「IEnumerable」として使用されている可能性があります
IQueryable インターフェースを実装するオブジェクトは、このインターフェースの特定の実装を使用して LINQ プロバイダー(通常はリモートデータベース)によって処理されることを目的としています。
しかし、 IQueryable は IEnumerable から継承されているため、 IQueryable オブジェクトが渡され、 IEnumerable オブジェクトとして処理される場合があり、すべての処理がローカルマシン上で実行されることを意味します。 このような暗黙の変換はテスト環境では問題になりませんが、本番環境では大きなパフォーマンスへの影響を与えることがあります。
データベースから IQueryable オブジェクトを取得すると仮定します:
IQueryable<Resource> resources = myDb.GetResources();
... そしてあなたのコードベースのどこかに、空の項目をフィルタリングする便利な拡張メソッドがあります:
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T> items)
{
return items.Where(x => x != null);
}
次に、クエリ可能オブジェクトをどのように使用できるかを見てみましょう。
// 'Where' will be processed in the database server and we just get the result:
var notNullResources1 = resources.Where(x => x != null);
// We will first get all Resource objects from the database
// and then process them locally.
// Also, 'notNullResources2' will be of the 'IEnumerable' type,
// so all other processing of this object will be done locally as well.
var notNullResources2 = resources.WhereNotNull();
JetBrains Rider はそのような変換を検出し、明示的に修正する提案を行います:
var notNullResources2 = resources.AsEnumerable().WhereNotNull();
別の例として、メソッドグループや式ツリーは、この場合 'Expression' オブジェクトとして渡すべきではなく、そのため同じインスペクションがトリガーされます。 ここでも同じ暗黙の変換(IEnumerable )が発生し、JetBrains Rider が呼び出しに明示的な .AsEnumerable() を追加することを提案します:
public static Func<object, bool> NotNullCondition => (x) => x != null;
public static void Test(IQueryable<object> resources)
{
if (resources != null)
{
var notNullResources =
resources.Select(NotNullCondition);
}
}
public static Func<object, bool> NotNullCondition => (x) => x != null;
public static void Test(IQueryable<object> resources)
{
if (resources != null)
{
var notNullResources =
resources.AsEnumerable().Select(NotNullCondition);
}
}
2026 年 6 月 12 日