本页使用了标题或全文手工转换

语言集成查询

维基百科,自由的百科全书
跳转至: 导航搜索

语言集成查询英文: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;
    }

擴展方法 (Extension method)[编辑]

Lambda表達式 (Lambda expression)[编辑]

表達式樹 (Expression tree)[编辑]

標準查詢運算子 (Standard query operators)[编辑]

操作符 类别 语义 示例
Where 筛选操作符(Restriction) Where(Predicate) Dim lowNums = numbers.Where(Function(num) num < 5)
Select 投影操作符(Projection) Select(匿名函数) Dim lowNums = numbers.Select(Function(num) num*num)
SelectMany 投影操作符(Projection) 返回多行结果,用于多表的交叉连接(cross join) Dim res = Employees.SelectMany(Function(e) e.Family.Select(Function(c)c.name))
Skip 分块操作符(Partitioning) 跳过前n个元素 Dim res=data.Skip(4)
SkipWhile 分块操作符(Partitioning) 跳过起始处使条件为真的所有元素 Dim res=data.SkipWhile(Function(i) i%2 = 0)
Take 分块操作符(Partitioning) 返回开头之处的n个元素 Dim res=data.Take(3)
TakeWhile 分块操作符(Partitioning) 返回起始处使条件为真的所有元素 Dim res=data.TakeWhile(Function(i) i%3 = 0)
Join 连接操作符 内连接两个或多个表,仅限于Equals运算符 from sup in suppliers join cust in customers on sup.Country equals cust.Country
GroupJoin 连接操作符 类似于LEFT OUTER JOIN,右侧集合匹配于左侧集合键值的元素被分组 From cust In customers Group Join ord In orders On cust.CustomerID Equals ord.CustomerID Into CustomerOrders = Group, OrderTotal = Sum(ord.Total)
Concate 合并操作符 用于连接两个序列 returnValue = firstSeq.Concat(secondSeq)
OrderBy 排序操作符(Ordering) Dim query As IEnumerable(Of Person) = Persons.OrderBy(Function(p) p.Age)
OrderByDescending 排序操作符(Ordering)
ThenBy 排序操作符(Ordering)
ThenByDescending 排序操作符(Ordering)
Reverse 排序操作符(Ordering)
GroupBy 分组操作符 Dim numbers = {5, 4, 1, 3, 9, 8, 6, 7, 2, 0}
Dim numberGroups = From num In numbers Group num By remainder5 = (num Mod 5) Into numGroup = Group Select New With {.Remainder = remainder5, .numbers = numGroup}
Distinct 集合操作符 去重复
Union 集合操作符 集合并
Intersect 集合操作符 集合交
Except 集合操作符 集合差
AsEnumerable 转换操作符 用于把一个IEnumerable的派生类型转化为IEnumerable类型
AsQueryable 转换操作符 IEnumerable(Of T)转化为IQueryable(Of T).
ToArray 转换操作符 转换为数组
ToList 转换操作符 转换为List
ToDictionary 转换操作符 转换为一对一的字典(键-值对的集合)
ToLookup 转换操作符 转换为一对多的字典(键-值集的集合)
OfType 转换操作符 获取指定类型的元素组成一个数组 object[] numbers = { null, 1.0, "two", 3, "four", 5, "six", 7.0 };
var doubles = numbers.OfType<double>();
Cast 转换操作符 把序列的所有元素转换为指定类型
SequenceEqual 相等操作符 两个序列的元素依次相同返回真。使用元素所属类的IEqualityComparer(Of T) 泛型界面做相等比较
First 元素操作符 返回序列第一个元素(或满足条件第一个元素),没有则异常
FirstOrDefault 元素操作符 返回序列第一个元素,没有则返回空或默认值
Last 元素操作符 返回序列最后一个元素,没有则异常
LastOrDefault 元素操作符 返回序列最后一个元素,没有则返回空或默认值
Single 元素操作符 返回序列唯一元素,如果没有元素或多个元素则异常
SingleOrDefault 元素操作符 返回序列唯一元素,如果没有元素或多个元素则空或默认值
ElementAt 元素操作符 返回序列指定元素,失败则异常
ElementAtOrDefault 元素操作符 返回序列指定元素,失败则空或默认值
DefaultIfEmpty 元素操作符 返回序列,如果序列为空则返回元素的默认值 For Each number As Integer In numbers.DefaultIfEmpty()〈br> output.AppendLine(number)
Next
All 序列元素数量操作符 序列所有元素满足条件则为真
Any 序列元素数量操作符 序列有一个元素满足条件则为真
Contains 序列元素数量操作符 是否包含一个元素
Count 统计操作符 计数,可选一个谓词 int oddNumbers = numbers.Count(n => n % 2 == 1);
LongCount 统计操作符 计数,返回Int64类型
Sum 统计操作符 求和,可选对一个lambda函数表达式 double totalChars = words.Sum(w => w.Length);
Min 统计操作符 最小值,可选对一个lambda函数表达式 int shortestWord = words.Min(w => w.Length);
Max 统计操作符
Average 统计操作符
Aggregate 统计操作符 参数为一个委托,在序列的每个元素上执行该委托。委托的第一个参数为当前累计值,第二个参数为当前元素,返回值为新的累计值 Dim reversed As String = words.Aggregate(Function(ByVal current, ByVal word) word & " " & current)
equals/Equals 关键字 用于Join子句
from/From 关键字
in/In 关键字 指出数据源
into/Into 关键字 用于Group By子句
key 关键字 用于Group By子句的无名类型
let 关键字 给表达式定义别名 From prod In products Let Discount = prod.UnitPrice * 0.1 Where Discount >= 50 Select prod.ProductName, prod.UnitPrice, Discount
Group 关键字 在GroupBy子句的Into中用于辨识分组结果 From num In numbers Group num By remainder5 = (num Mod 5) Into Group
Range 方法 产生一个整数序列 From n In Enumerable.Range(100, 50)
Repeat 方法 产生一个整数序列 From n In Enumerable.Repeat(7, 10)

LINQ的各式言語支援度[编辑]

下列的言語支持LINQ。

註:C++/CLI尚未支援LINQ。但是有第三方的C++套件[1],以及第三方的PHP套件[2]

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<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);
}

Visual Studio支持[编辑]

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

语言扩展[编辑]

微软同样提供了LINQExtender,允许使用者在不了解LINQ实现细节的情况下,编写自己的LINQ扩展。 如:LINQ to Twitter,LINQ to Oracle,LINQ to Active Directory等

參考資料[编辑]

相關[编辑]

外部連結[编辑]