語言集成查詢

語言集成查詢（Language Integrated Query，縮寫：LINQ），發音"link"，是微軟的一項技術，新增一種自然查詢的SQL語法到.NET Framework的程式語言中，目前可支援C#以及Visual Basic .NET語言。2007年11月19日隨.NET Framework 3.5發佈了LINQ技術。
包括LINQ to Objects、LINQ to SQL、LINQ to Datasets、LINQ to Entities、LINQ to Data Source、LINQ to XML/XSD等。

**語言風格**
LINQ依賴於語言的多項新增風格，來展示出查詢語言的擴充性。例如：C#:

**匿名型別**
匿名型別（Anonymous type）是C# 3.0與Visual Basic 9.0新增的功能，它允許開發人員可以使用不具型別的方式建立新的資料結構，而真正的型別在編譯時期，由C# (或VB) Compiler自動產生，並寫入編譯目的檔中，它可以讓開發人員能夠很簡單利用匿名型別建立物件，LINQ中的select指令即是利用這種特性來建立回傳物件。
匿名類型本質上是表達元組（tuple），採用值語義。
下列使用匿名型別的程式碼：
WebGet
public IQueryable GetCategoryByName(string CategoryName)
{
try
{
var query = base.CurrentDataSource.Categories.Where
　　　　　　　　　("it.CategoryName = @Name", new ObjectParameter { new ObjectParameter("Name", CategoryName) });
}
catch (Exception)
{
throw;
}
return query;
} 
會由編譯器改寫為：
WebGet
public IQueryable GetCategoryByName(string CategoryName)
{
IQueryable CS$1$0000;　// 由編譯器改寫而成。
try
{
CS$1$0000 = base.CurrentDataSource.Categories.Where
　　　　　　　　　("it.CategoryName = @Name", new ObjectParameter { new ObjectParameter("Name", CategoryName) });
}
catch (Exception)
{
throw;
}
return CS$1$0000;
}

**擴展方法 (Extension method)**

**Lambda表達式 (Lambda expression)**

**表達式樹 (Expression tree)**

**查詢表達式語法**
from RangeVariable in IEnumerable或IQueryable的Collection



**流利語法**
LINQ查詢時有兩種語法可供選擇：查詢表達式語法（Query Expression）和流利語法（Fluent Syntax）。前者使用查詢運算符；後者利用System.Linq.Enumerable類中定義的擴展方法和Lambda表達式方式進行查詢。CLR本身並不理解查詢表達式語法，它只理解流利語法。編譯器負責把查詢表達式語法編譯為流利語法。
以下是一個示例LINQ方法語法的查詢，返回數組中的偶數：
int ints={1,2,3,4};
var result = ints.Where(p => p % 2 == 0).ToArray();
對比流利語法和C#的傳統語法：
//   extension methods make LINQ elegant
IEnumerable query = names
.Where(n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select(n => n.ToUpper());

//   static methods lose query's fluency
IEnumerable query2 =
Enumerable.Select(
Enumerable.OrderBy(
Enumerable.Where(names, n => n.Contains("a")
), n => n.Length
), n => n.ToUpper()
);

**標準查詢運算子 (Standard query operators)**
System.Linq.Enumerable靜態類聲明瞭一套標準查詢操作符（Standard Query Operators，SQO）方法集合。基本語法如下：
using (var db = new EntityContext())
{
var roles = from o in db.Users
where o.Account == "Apollo"
select o.Roles;
…
}
標準查詢操作符和Lambda表達式的關係非常密切。編譯器會將上述表達式轉化為下述以Lambda表達式為參數的顯式擴展方法調用序列：
using (var db = new EntityContext())
{
var roles = db.Users.Where(o => o.Account == "Apollo").Select(o => o.Roles);
}

**LINQ的各式言語支援度**
下列的言語支持LINQ。
*C# 3.0
*F# 1.1.8.1
*Visual Basic 2008（9.0）
註：C++/CLI尚未支援LINQ。但是有第三方的C++套件，以及第三方的PHP套件

**LINQ的範例**
一個簡單例子：
using System;
using System.Linq;
namespace DuckTyping
{
internal class Program
{
private static void Main()
{
int array = { 1, 5, 2, 10, 7 };  
// Select squares of all odd numbers in the array sorted in descending order
var results = from x in array
where x % 2 == 1
orderby x descending
select x * x;
foreach (var result in results)
{
Console.WriteLine(result); 
}
}
}
}
輸出：
49
25
1
另一個例子：
// the Northwind type is a subclass of DataContext created by SQLMetal
// Northwind.Orders is of type Table
// Northwind.Customers is of type Table
Northwind db = new Northwind(connectionString);

// use 'var' keyword because there is no name for the resultant type of the projection

var q =  from o in db.Orders
from c in db.Customers
where o.Quality == "200" && (o.CustomerID == c.CustomerID)
select new { o.DueDate, c.CompanyName, c.ItemID, c.ItemName };

// q is now an IEnumerable, where T is the anonymous type generated by the compiler
foreach (var t in q)
{
// t is strongly typed, even if we can't name the type at design time

Console.WriteLine("DueDate Type = {0}", t.DueDate.GetType());
Console.WriteLine("CompanyName (lowercased) = {0}", t.CompanyName.ToLower());
Console.WriteLine("ItemID * 2 = {0}", t.ItemID * 2);
}

**Visual Studio支持**
LINQ目前由Visual Studio 2008、2010、2012、2013、2015、2017、2019支持。

**語言擴展**
微軟同樣提供了LINQExtender，允許使用者在不瞭解LINQ實現細節的情況下，編寫自己的LINQ擴展。
如：LINQ to Twitter,LINQ to Oracle,LINQ to Active Directory等

**參考文獻**

**外部連結**
  Official Microsoft LINQ Project（已失效）-  101 C# LINQ Samplesdate=20080914215959 -  101 Visual Basic LINQ Samplesdate=20081007020322 -  Microsoft LINQ forum-  LINQ page on NetFXGuide.com-  LINQ wikidate=20080425224159 -  LINQExtenderdate=20090813171541 

**參見**
 物件關聯對映（ORM）