参考:MSDN:语言集成查询 (LINQ)
我在工作中一般只写简单的LINQ,复杂的都是先用一般写法写出来然后用VS的插件ReSharper转换。毕竟LINQ简洁了当但是有时候还是不太直观
查询是一种从数据源检索数据的表达式, 查询通常用专门的查询语言来表示。LINQ最大的优势就是可使用相同的基本查询表达式模式来查询和转换 SQL 数据库、ADO .NET 数据集、XML 文档和流以及 .NET 集合中的数据,极大的降低了学习成本提高了代码维护性和可读性。
简单例子,以下代码就是从customers中获取city为London或者Paris的成员,然后排序。比起传统的foreach+if else是不是简单很多了呢。
var queryLondonCustomers = from cust in customers
where cust.City == "London" || cust.City == "Paris"
orderby cust.Name ascending
select cust;
// queryCustomersByCity is an IEnumerable>
var queryCustomersByCity =
from cust in customers
group cust by cust.City;
// customerGroup is an IGrouping
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}
分组以后还可以继续筛选
// custQuery is an IEnumerable>
var custQuery =
from cust in customers
group cust by cust.City into custGroup
where custGroup.Count() > 2
orderby custGroup.Key
select custGroup;
var innerJoinQuery =
from cust in customers
join dist in distributors on cust.City equals dist.City
select new { CustomerName = cust.Name, DistributorName = dist.Name };
LINQ文档中的大多数查询是使用 查询语法编写的。 但是在编译代码时,查询语法必须转换为针对 .NET 公共语言运行时 (CLR) 的方法调用。 这些方法调用会调用标准查询运算符(名称为 Where
、Select
、GroupBy
、Join
、Max
和 Average
等)。 同时可以可以使用方法语法(而不查询语法)来直接调用它们。
查询语法和方法语法在语义上是相同的,但是许多人发现查询语法更简单且更易于阅读。 某些查询必须表示为方法调用。 例如,必须使用方法调用表示检索与指定条件匹配的元素数的查询。 还必须对检索源序列中具有最大值的元素的查询使用方法调用。 System.Linq命名空间中的标准查询运算符的参考文档通常使用方法语法。 因此,即使在开始编写 LINQ 查询时,熟悉如何在查询和查询表达式本身中使用方法语法也十分有用。
以下例子中分别使用了两种语法,效果是一样的
class QueryVMethodSyntax
{
static void Main()
{
int[] numbers = { 5, 10, 8, 3, 6, 12};
//查询语法 Query syntax:
IEnumerable numQuery1 =
from num in numbers
where num % 2 == 0
orderby num
select num;
//方法语法 Method syntax:
IEnumerable numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
foreach (int i in numQuery1)
{
Console.Write(i + " ");
}
Console.WriteLine(System.Environment.NewLine);
foreach (int i in numQuery2)
{
Console.Write(i + " ");
}
// Keep the console open in debug mode.
Console.WriteLine(System.Environment.NewLine);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/*
Output:
6 8 10 12
6 8 10 12
*/
上面例子的方法语法中将表达式(num => num % 2 == 0)作为内联参数传递给了.Where,这就是Lambda表达式。=>就是Lambda运算符,读作转到。运算符左侧是输入变量,由于编译器可以推断出输入变量的类型,故不需要加上类型修饰符。
说白了,lambda表达式是一个未命名的方法,代替一个委托实例。
delegate int Converter (int i);
Converter sqr = x => x * x;
Console.WriteLine (sqr(3)); // 9
Lambda表达式最常用于Func和Action委托。我们可以重写上面的代码如下:
Func sqr = x => x * x;
还可以写成:
Converter sqr = x => x * x;
例子2:
Func totalLength = (s1, s2) => s1.Length + s2.Length;
int total = totalLength ("a", "the");