语言集成查询
语言集成查询(英語:,縮寫: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;
}
標準查詢運算子 (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的範例
一个简单例子:
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、2017、2019支持。
语言扩展
微软同样提供了LINQExtender,允许使用者在不了解LINQ实现细节的情况下,编写自己的LINQ扩展。 如:LINQ to Twitter,LINQ to Oracle,LINQ to Active Directory等
外部連結
参见
- 物件關聯對映(ORM)
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.