LINQとは何か?

C#

LINQはC#の便利機能の1つで、色んなデータを簡単に操作できるようになります。

今回はLINQとはどうゆうものか、その概念的な部分を説明します。

LINQとは

LINQとは Language Integrated Query の略で、日本語では統合言語クエリと言います。データベースやXMLなど様々なデータソースに対して、同じ書き方(統合言語)でデータを要求する機能(クエリ)です。

通常、データソースにアクセスするためには、データベースだとSQL、XMLだとDOM、…というようにそれぞれ固有の仕組みを用います。LINQを用いることで開発者は各データソースのアクセス手段を意識せずにプログラミングすることができるようになります。

LINQが使えるプログラミング言語としては、C#、F#、VBなどがあります。

LINQの種類

LINQでは操作するデータソースに応じて、LINQ to 〇〇(データソース名)と呼ばれます。例えば、LINQでオブジェクトを操作する仕組みをLINQ to Objects、XMLの場合はLINQ to XMLと言います。LINQ to 〇〇は数多存在するので、ここでは一例を紹介します。

  • LINQ to Objects
  • LINQ to SQL
  • LINQ to XML
  • LINQ to Twitter

LINQの仕組み

LINQでは専用のクエリ(以後LINQクエリと略記)を書くことで、データソースを操作することができます。このLINQクエリの操作対象はLINQ to Objectsとそれ以外(LINQ to SQLやLINQ to XMLなど)で異なります。それぞれの内部的な仕組みを見ていきましょう。

LINQ to Objectsの仕組み

LINQ to ObjectsではIEnumerableというインターフェイスを実装したクラスを扱います。つまり、配列やリストなどのコレクションが操作対象となります。

名前に惑わされてオブジェクト全体が操作対象と勘違いしないよう注意!

LINQクエリを使うことでコレクションを簡単に操作できるようになります。

LINQ to Objects以外の仕組み

LINQ to Objects以外ではLINQプロバイダーと呼ばれるクラスを扱います。このクラスにはIQueryableIQueryProviderの2つのインターフェイスが実装されています。

LINQクエリをLINQプロバイダーに送ることで、LINQプロバイダーはその内容に応じた処理をデータソースに対して行います。

LINQ to SQL や LINQ to XML など、一部のLINQプロバイダーは.NET Frameworkに用意されています。この他にもオリジナルのLINQプロバイダーを作ることも可能です。例えば、CSVファイルを操作するCSV用LINQプロバイダー、(APIを使って)Twitterのデータを操作するTwitter用LINQプロバイダーなど様々です。

LINQクエリの書き方

LINQクエリにはメソッド構文クエリ構文の2種類の書き方があります。

細かい書き方はデータの処理内容によって変わってくるので、ここでは大まかにどのように書くかを説明します。

メソッド構文

メソッド構文ではその名の通り、メソッドを使ってデータを操作します

例えば、1~4の数値が格納されたリストから偶数を取得する処理は、メソッド構文で次のように書きます。

// 元のリスト
List<int> numberList = new List<int> { 1, 2, 3, 4 };

// メソッド構文で偶数を抽出
IEnumerable<int> evenNumberList = numberList.Where(number => number % 2 == 0);

// evenNumberListの中身 => 2, 4

5行目のWhereがLINQ用のメソッド(以降LINQメソッドと略記)です。このメソッドは元となるデータソースから引数の条件に一致する要素を抽出します。

もう少し詳しく見ると…

まず、引数ではラムダ式が使われており、この部分を翻訳すると次のようになります。

number => number % 2 == 0

データソースの各要素をnumberという名前で宣言 => numberを2で割った余りが0かどうか(偶数かどうか)

Whereメソッドはラムダ式の=>以降に書かれた条件がTrueとなる要素を抽出します。

Whereメソッドには引数がありますが、引数を持たないLINQメソッドもあります。つまり、メソッド構文を大まかに書くと次のようになります。

データソース.LINQメソッド(データソースの各要素の変数名 => 処理内容);

もしくは

データソース.LINQメソッド();

クエリ構文

クエリ構文ではSQL文のような書き方でデータを操作します

メソッド構文と同じ例をクエリ構文で書くと次のようになります。

// 元のリスト
List<int> numberList = new List<int> { 1, 2, 3, 4 };

// クエリ構文で偶数を抽出
IEnumerable<int> evenNumberList = from number in numberList
                                  where number % 2 == 0
                                  select number;

// evenNumberListの中身 => 2, 4

5~8行目がクエリ構文となります。処理はメソッド構文と同じなので説明を省きます。

ここで登場するfrom, in, where, selectはクエリ構文専用のキーワードでと呼びます。クエリ構文は from句 + in句 から始まり、select句 もしくは group句 + by句 で終わります。この間にはwhere句のようなデータの処理内容を書きます。つまり、クエリ構文の大まかな形は次のようになります。

from データソースの各要素の変数名 in データソース
処理内容
select データソースの各要素の変数名;

もしくは

from データソースの各要素の変数名 in データソース
処理内容
select データソースの各要素の変数名 by ~;

クエリ構文では使えないLINQ機能があるので注意!

以下、筆者の主観的な意見です。

昔のコードを見るとクエリ構文がよく使われていますが、最近のコードではメソッド構文の方が多く使われていると思われます。クエリ構文とメソッド構文は組合わせることも可能ですが、可読性の点からおすすめしません。

コメント

タイトルとURLをコピーしました