语言集成查询

语言集成查询（英語：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<Categories> 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<Categories> GetCategoryByName(string CategoryName) { IQueryable<Categories> 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; } from RangeVariable in IEnumerable<T>或IQueryable<T>的Collection <Standard Query Operators> <lambda expression> <select or groupBy operator> <result formation> 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<string> query = names .Where(n => n.Contains("a")) .OrderBy(n => n.Length) .Select(n => n.ToUpper()); // static methods lose query's fluency IEnumerable<string> query2 = Enumerable.Select( Enumerable.OrderBy( Enumerable.Where(names, n => n.Contains("a") ), n => n.Length ), n => n.ToUpper() ); 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。 C# 3.0 F# 1.1.8.1 Visual Basic 2008（9.0） 註：C++/CLI尚未支援LINQ。但是有第三方的C++套件，以及第三方的PHP套件 一个简单例子： 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<Order> // Northwind.Customers is of type Table<Customer> 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<T>, 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); } LINQ目前由Visual Studio 2008、2010、2012、2013、2015、2017、2019支持。 微软同样提供了LINQExtender，允许使用者在不了解LINQ实现细节的情况下，编写自己的LINQ扩展。 如：LINQ to Twitter,LINQ to Oracle,LINQ to Active Directory等 LINQ for C++. [2014-02-18]. （原始内容存档于2014-02-16）.  PHPLinq. [2014-02-18]. （原始内容存档于2014-02-22）.  Official Microsoft LINQ Project（已失效） 101 C# LINQ Samples（页面存档备份，存于互联网档案馆） 101 Visual Basic LINQ Samples（页面存档备份，存于互联网档案馆） Microsoft LINQ forum LINQ page on NetFXGuide.com LINQ wiki（页面存档备份，存于互联网档案馆） LINQExtender（页面存档备份，存于互联网档案馆） 物件關聯對映（ORM）