# 統合言語クエリ

**統合言語クエリ** (**Language INtegrated Query**; **LINQ**, リンクと発音する) とは、.NET Framework 3.5において、様々な種類のデータ集合に対して**標準化された方法で**データを問い合わせること（クエリ）を可能にするために、言語に統合された機能のことである。開発ツールはVisual Studio 2008から対応している。

**統合言語問合せ**という表記も見られる。

## 例

C#による例を示す。このコードでは、`fruits`の中から"m"で始まるものを取り出し、それを`ret`に格納し、それをforeach文で順に出力している（実際には`ret`は遅延評価される）。

```
using System;
using System.Linq; // LINQ拡張メソッドの利用に必要。メソッド構文ではなくクエリ構文を使用する場合でも必要となる。

public class Test
{
 public static void Main()
 {
 string[] fruits =
 {
 "apple",
 "cherry",
 "melon",
 "orange",
 "marron",
 "mango",
 };
 // クエリ構文
 Console.WriteLine("Query Syntax");
 {
 // fromからselectまでの一連の式がLINQクエリ式である。
 var ret = from x in fruits
 where !string.IsNullOrEmpty(x) && x[0] == 'm'
 select x;
 foreach (var e in ret)
 {
 Console.WriteLine(e);
 }
 }
 // メソッド構文
 Console.WriteLine("Method Syntax");
 {
 // オブジェクトをフィルタリングする条件（述語）を、ラムダ式で指定する。
 var ret = fruits.Where(x => !string.IsNullOrEmpty(x) && x[0] == 'm');
 foreach (var e in ret)
 {
 Console.WriteLine(e);
 }
 }
 }
}

```

## 言語仕様

LINQに対応する言語は、LINQを自然に導入するための新しい言語仕様が併せて追加されている。代表的な例を以下に示す。

クエリ式
SQLのような問い合わせ言語風の文法が取り入れられた。これはメソッド構文の構文糖となっている。
拡張メソッド
同様のデータ構造に対して後から操作を追加するために取り入れられた。例えば、LINQ to Objectの場合は`IEnumerable`インターフェイスの拡張メソッドとして標準クエリ演算子を含むメソッド群が追加された。
ラムダ式
従来の匿名メソッドに取って代わる構文として導入された。引数の型が省略できることや、式木に変換することができることで、自然にLINQを導入できるようにした。
匿名型
クエリの結果や途中の値を一時的な値の組合せで保持できるよう導入された。クエリ結果の格納を意図しているため、匿名型の各値は読み取り専用プロパティとなっている。
C#における仕様の詳細はC# 3.0からの仕様を参照されたい。

## 標準クエリ演算子

主な標準クエリ演算子を挙げる。

### 制限演算子

* `Where`は、指定した述語をもとに要素のフィルタ処理を行う。高階関数の**filter**に相当する。

### プロジェクション演算子

* `Select`は、指定した評価関数をもとに要素のプロジェクションを行う。高階関数の**map**に相当する。
* `SelectMany`は、指定した評価関数をもとに1対多のプロジェクションを行う。

### 結合演算子

* `Join`は指定したキーセレクタをもとに等価結合を行う。
* `GroupJoin`は指定したキーセレクタをもとにグループ化結合を行う。

### 順序付け演算子

* `OrderBy`,`ThenBy`は指定したキーセレクタをもとに結果の順序を指定する。

### グループ化演算子

* `GroupBy`は指定したキーセレクタをもとにグループ化を行う。

### 集計演算子

* `Aggregate`は、指定した累積関数をもとにシーケンスの集計を行う。高階関数の**fold**に相当する。

## データソース

LINQはサードパーティーによるものを含め、あらゆる種類のデータソースに対して適用することができる。これは、標準クエリ演算子に対応する機能を拡張メソッドとしてデータソースに追加することで実現している。

従来では同種のデータ型やオブジェクトの集合に対して列挙やソート、フィルタを効率的に扱うために配列 (Arrayクラス) やコレクションオブジェクトが用いられた。一方、データベースやXML上のデータ集合はADO.NETによってデータセットとして取り扱われており異なる操作が必要であった。LINQによって、これらのオブジェクトやデータセットを区別せず共通的に扱うことが可能となった。

例えば、マイクロソフトによるものでは次のような実装がある。

* LINQ to Objects (あらゆるコレクション/列挙子をLINQクエリで操作可能にする)
* LINQ to XML (XLinq)
* LINQ to ADO.NET
	+ LINQ to SQL (DLinq / SQL Server専用)
	+ LINQ to Entities (SQL Server / Oracle Database / MySQL / SQLite等)
	+ LINQ to DataSet (DataSetに対する拡張メソッドにより、LINQクエリを記述可能とする)
* Azure Table Storage (Windows AzureのキーバリューストアでLINQクエリを記述可能とする)

サードパーティー製データソースとしては、以下が挙げられる。

* LINQ to Twitter - ツイッターの情報をソースとする。

## LINQに対応する言語

次の言語がLINQに対応する。

* C# 3.0 以降
* F# 1.1.8.1 以降
* Visual Basic 9.0 以降
* Delphi Prism 2009 (Oxygene)

C++/CLIはLINQに対応する予定はなく、従来通りの構文でLINQ関係のライブラリを使用できるのみである。

## その他の言語での実装

LINQは、LINQの思想に感化された人々により、マイクロソフト系のプログラミング言語にとどまらず、さまざまなプログラミング言語向けの実装が行われている。

* jLinq - JavaScriptでの実装
* JSINQ - JavaScriptでの実装
* linq.js - JavaScriptでの実装
* Chris Pietschmann's LINQ to JavaScript - JavaScriptでの実装
* PHPLinq - PHPでの実装
* Quaere - Javaでの実装
* JaQue - Javaでの実装.
* JaQu - Javaでの実装
* Querydsl - Javaでの実装
* pynq - Pythonでの実装
* go-linq - Goでの実装

* 『Oracle Database 12cによるアプリケーション開発』（PDF）（レポート）Oracle、2017年1月。

* LINQ (統合言語クエリ) | Microsoft Docs
* LINQ: .NET Language Integrated Query | Microsoft Docs
* The LINQ Project (Microsoft Wordの.doc)