C# 的LINQ语法类似数据库的查询方法,是一种数据集合的查询语法,LINQ可以直接查询数据库、泛型、以容器、以及xml文档。什么意思呐?我们对于一个集合可能操作就是通过循环,给出判断条件,然后满足条件的话就把这个元素添加到一个新的集合内返回就行啦,但是C#提供了另外的方法,就是用LINQ查询语法,用类似SQL语法对可查询对象进行筛选,就这个开发效率就很高了,而且这样的写法还很方便。
初次尝试使用LINQ语法,下面有对几种集合类型进行查询例子,语法非常容易懂,可以工具可以好好利用。
使用LINQ有三个步骤。
如下面 代码例子所示
如下对数组进行查询 大于100的元素
//创建数据源
int[] intList = { 32, 35, 43, 654, 76, 56, 57, 453, 3542, 46 };
//创建查询语句
IEnumerable<int> searchRes = from item in intList
where item >100
select item;
//执行查询
foreach(var item in searchRes)
{
Console.WriteLine(item);
}
//结果如下
654
453
3542
如下对字符串列表查询
//创建数据源
List<string> stringList = new List<string>() {"Helan","Linken", "Black", "Brownd", "Kindey" };
//创建查询语句
IEnumerable<string> stringSearchList = from item in stringList
where item.StartsWith("B") || item.StartsWith("K")
select item;
//执行查询
foreach(var item in stringSearchList)
{
Console.WriteLine(item);
}
//结果如下
Black
Brownd
Kindey
//创建数据源
IEnumerable<double> doubeList = new double[]{ 32.4, 3.25, 35.4, 3.65, 4.74, 3.575, 4.6675 };
//创建查询语句
var doubleSearchList = from item in doubeList
where item > 20.11
select item;
//执行查询
foreach(var item in doubleSearchList)
{
Console.WriteLine(item);
}
//结果如下
32.4
35.4
对 这种非泛型查询需要指定 数据 对象的类型, 不然推断不出来是什么类型 ,因为其实泛型已经指明了数据项的类型
//创建数据源
ArrayList arrayList = new ArrayList() { 42, 34, 43, 434, -4, 354, 65, 754, 7, -43, 764, 2, };
//创建查询语句
var arrayListRes = from int item in arrayList
where item <= 0
select item;
//执行查询
foreach(var item in arrayListRes)
{
Console.WriteLine(item);
}
//查询结果
-4
-43
所谓获取数据源,其实在上面例子中已经说明很清晰啦,数据源其实就是一个数据集合,我们需要指定一个集合作为我们查询的基础条件,在 LINQ 查询中,第一步是指定数据源。 在 LINQ 查询中,先使用 from 子句引入数据源以及数据项。
//创建数据源
IEnumerable<double> doubeList = new double[]{ 32.4, 3.25, 35.4, 3.65, 4.74, 3.575, 4.6675 };
//from 则是引入数据源 以及指定数据项
var doubleSearchList = from item in doubeList
....
选择对象其实就是 select item,select 子句生成查询结果并指定每个返回的元素的“形状”或类型。 例如,可以指定结果包含的是整个 Customer 对象、仅一个成员、成员的子集,还是某个基于计算或新对象创建的完全不同的结果类型。 这就牛逼了,意思就是说 满足条件的 数据项 可以对其进行一定的操作再返回
示例:选择以 B ,K 开头的字符串并全部转为大写
List<string> stringList = new List<string>() {"Helan","Linken", "Black", "Brownd", "Kindey" };
IEnumerable<string> stringSearchList = from item in stringList
where item.StartsWith("B") || item.StartsWith("K")
select item.ToUpper();
foreach(var item in stringSearchList)
{
Console.WriteLine(item);
}
//结果
BLACK
BROWND
KINDEY
筛选其实就是使用一定的条件过滤出我们想要的结果,使用的关键字就是 where ,在上面的很多例子里都使用了where 作为筛选条件。
那就知道了 where 后面跟一个能计算出为 bool true 的表达式即可
能返回 true 的表达式就相对灵活了 可以是
var queryLondonCustomers = from cust in customers
where cust.City == "London"
select cust;
where cust.City == "London" && cust.Name == "Devon"
where cust.City == "London" || cust.City == "Paris"
一个查询表达式可以包含多个 where 子句,一个子句可以包含多个where子表达式。(不推荐这么用)
如下,结果都一样,第二个比较费脑子些
// 数据源
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
// 查询表达式
var queryLowNums2 =
from num in numbers
where num < 5 && num % 2 == 0
select num;
// 执行筛选
foreach (var s in queryLowNums2)
{
Console.Write(s.ToString() + " ");
}
Console.WriteLine();
// 查询表达式
var queryLowNums3 =
from num in numbers
where num < 5
where num % 2 == 0
select num;
// 执行筛选
foreach (var s in queryLowNums3)
{
Console.Write(s.ToString() + " ");
}
//结果
// 4 2 0
// 4 2 0
在查询表达式中,orderby 子句可对满足条件的序列或子序列(组)以升序或降序排序。 同时我们可以使用一个个或多个次级排序操作,可以指定多个键来排序。 元素类型的默认比较器执行排序。 默认排序顺序为升序。 还可以指定自定义比较器。
排序的方式有两种:一种升序,一种降序
最简单的使用用法之一如下:
// 待查询类的属性
public class Customer
{
public string Name{get;set;}
public string City{get;set;}
}
//数据源
List <Customer> customers = new List <Customer>(){/*一系列初始化*/};
//查询London 城市的Name, 按照升序排列A-Z排序
//若 对结果进行从 Z 到 A 的逆序排序,使用 orderby descending即可
var queryLondonCustomers3 =
from cust in customers
where cust.City == "London"
orderby cust.Name ascending
select cust;
简单排序查询-示例
// 创建数据源
string[] fruits = { "cherry", "apple", "blueberry" };
// 查询语句-升序
IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //默认升序
select fruit;
// 查询语句-降序
IEnumerable<string> sortDescendingQuery =
from w in fruits
orderby w descending
select w;
// 执行查询
Console.WriteLine("Ascending:");
foreach (string s in sortAscendingQuery)
{
Console.WriteLine(s);
}
// 执行查询
Console.WriteLine(Environment.NewLine + "Descending:");
foreach (string s in sortDescendingQuery)
{
Console.WriteLine(s);
}
//结果
Ascending:
apple
blueberry
cherry
Descending:
cherry
blueberry
apple
除了可以直接排序一次,还可以使用次要排序,次要排序的意思其实就是说,在第一轮排序内部的肯定在同级下面有很多相同的数据,我们还可以对其进一步这个已排序组内再进行一次排序。下面看官网的示例就知道啦
// 数据源的数据项的具体描述
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
}
//产生一个数据集合
public static List<Student> GetStudents()
{
List<Student> students = new List<Student>
{
new Student {First="Svetlana", Last="Omelchenko", ID=111},
new Student {First="Claire", Last="O'Donnell", ID=112},
new Student {First="Sven", Last="Mortensen", ID=113},
new Student {First="Cesar", Last="Garcia", ID=114},
new Student {First="Debra", Last="Garcia", ID=115}
};
return students;
}
//主函数执行
static void Main(string[] args)
{
// 产生数据源
List<Student> students = GetStudents();
// 创建查询
IEnumerable<Student> sortedStudents =
from student in students
orderby student.Last ascending, student.First ascending
//先按照 Last 升序排,在升序组内再安装 First 排序即可
select student;
// 执行查询
Console.WriteLine("sortedStudents:");
foreach (Student student in sortedStudents)
{
Console.WriteLine(student.Last + " " + student.First);
}
//这里涉及到分组的知识,分组的基本条件是要排序后再分组,
var sortedGroups =
from student in students
orderby student.Last, student.First //忽略了 ascending 关键词
group student by student.Last[0] into newGroup //分组按照 Last首字母,分组后把分组结果塞到newGroup
orderby newGroup.Key //分组的集合再排序一次
select newGroup;
// 执行查询
Console.WriteLine(Environment.NewLine + "sortedGroups:");
foreach (var studentGroup in sortedGroups)
{
Console.WriteLine(studentGroup.Key);
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}", student.Last, student.First);
}
}
}
/* Output:
sortedStudents:
Garcia Cesar
Garcia Debra
Mortensen Sven
O'Donnell Claire
Omelchenko Svetlana
sortedGroups:
G
Garcia, Cesar
Garcia, Debra
M
Mortensen, Sven
O
O'Donnell, Claire
Omelchenko, Svetlana
*/
分组和数据的基本一致,要使用分组的特性就需要使用group 关键字, 在分组语句中 毫无疑问需要我们指定分组的方式,这个方式一般通过统一的类型,就是键 key。分组的结果就是一个键值对, 例如,我们可指定按 City 对结果进行分组,使来自 London 或 Paris 的所有客户位于单独的组内。
// queryCustomersByCity 是这种类型: IEnumerable>
var queryCustomersByCity =
from cust in customers
group cust by cust.City;
// customerGroup 类型结构 IGrouping
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}