0Pricing
C# Academy · レッスン

LINQプロバイダーにおける式ツリー

プロバイダーが式をクエリに変換する仕組みを確認します。

「LINQプロバイダーにおける式ツリー」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

LINQ に式ツリーが必要な理由

LINQ には 2 つの形式があります。IEnumerable<T> はラムダ式をメモリ内で実行します。IQueryable<T> はラムダ式を式ツリーとして受け取り、プロバイダーが SQL などの別の言語に変換できるようにします。

IEnumerable と IQueryable の違い

違いはパラメーターの型にあります。IEnumerable.Where はコンパイル済みの Func<T,bool> を受け取るのに対し、IQueryable.Where はツリーである Expression<Func<T,bool>> を受け取ります。

using System;
using System.Linq;
using System.Linq.Expressions;

int[] nums = { 1, 2, 3, 4 };
// IEnumerable path: lambda is a compiled delegate
var evens = nums.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(",", evens)); // 2,4

クエリはデータのまま

IQueryable では、ラムダ式は式ツリーとして取得され、まだ実行されません。プロバイダーはツリーを調査してクエリを構築します。

using System;
using System.Linq;
using System.Linq.Expressions;

IQueryable<int> q = new[] { 1, 2, 3, 4, 5 }.AsQueryable();
var filtered = q.Where(n => n > 2);
Console.WriteLine(filtered.Expression.NodeType); // Call (a method-call tree)

クエリ式を調査する

クエリ可能なオブジェクトの Expression プロパティを使うと、プロバイダーが変換するツリーを取得できます。

using System;
using System.Linq;

var q = new[] { 10, 20, 30 }.AsQueryable().Where(x => x >= 20);
Console.WriteLine(q.Expression.ToString().Contains("Where")); // True

実行ではなく変換

Entity Framework のようなプロバイダーはツリーをたどり、WHERE Age > 18 のような SQL を生成します。C# の述語はクライアント上で実行されず、データベースが処理を行います。

IQueryProvider の役割

IQueryable は IQueryProvider を保持します。クエリを列挙すると、プロバイダーは式ツリーを受け取り、その実行方法を決定します。

using System;
using System.Linq;

var q = new[] { 1, 2, 3 }.AsQueryable();
Console.WriteLine(q.Provider.GetType().Name); // EnumerableQuery (the in-memory provider)

遅延実行

ツリーが変換されて実行されるのは、列挙するとき(例: ToList、foreach)だけです。それまでは、自由に組み合わせられる純粋なデータとして保持されます。

using System;
using System.Linq;

var q = new[] { 1, 2, 3, 4 }.AsQueryable()
    .Where(n => n > 1)
    .Select(n => n * 10);
// nothing has run yet; now force it:
Console.WriteLine(string.Join(",", q.ToList())); // 20,30,40

クエリを組み立てる

各演算子が式ツリーに追加されるため、クエリを段階的に構築できます。実行時には、プロバイダーが全体を確認できます。

using System;
using System.Linq;

var baseQuery = new[] { 5, 15, 25, 35 }.AsQueryable();
var q = baseQuery.Where(n => n > 10);
q = q.Where(n => n < 30); // composed: 10 < n < 30
Console.WriteLine(string.Join(",", q.ToList())); // 15,25

変換できないもの

プロバイダーが変換できるのは、理解できる操作だけです。任意の C# メソッドを呼び出す述語は、SQL に相当するものがないため、実行時に例外をスローすることがあります。

独自のプロバイダーを作成する

カスタムプロバイダーは IQueryProvider を実装し、ExpressionVisitor を使ってツリーをたどり、各ノードを対象のクエリ言語に変換します。

まとめ

ここでの重要な点は、同じラムダ式が IEnumerable ではデリゲートになり、IQueryable では変換を可能にするツリーになることです。

using System;
using System.Linq;
using System.Linq.Expressions;

Expression<Func<int, bool>> predicate = n => n > 2;
var data = new[] { 1, 2, 3, 4 };
// IEnumerable needs a delegate:
Console.WriteLine(string.Join(",", data.Where(predicate.Compile()))); // 3,4
// IQueryable accepts the tree directly:
Console.WriteLine(string.Join(",", data.AsQueryable().Where(predicate))); // 3,4

クイックチェック

LINQ プロバイダーで式ツリーが果たす役割を確認します。

まとめ

LINQ プロバイダーが式ツリーを使用する方法を学びました。

  • IEnumerable はコンパイル済みの Func を使用し、IQueryable は Expression<Func> ツリーを使用します。
  • プロバイダーはツリーを実行するのではなく、SQL などに変換します。
  • 実行は列挙するまで遅延されます。
  • 変換可能な操作だけが機能し、任意のメソッドは失敗することがあります。

よくある質問

「LINQプロバイダーにおける式ツリー」レッスンは無料ですか?

はい。「LINQプロバイダーにおける式ツリー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「LINQプロバイダーにおける式ツリー」で何を学びますか?

プロバイダーが式をクエリに変換する仕組みを確認します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「LINQプロバイダーにおける式ツリー」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 式ツリーとは
  2. 式の手動構築
  3. 式のコンパイルと実行
  4. LINQプロバイダーにおける式ツリー
← C# Academyに戻る