LINQ用法学习
基本语法
详细信息参阅LINQ 查询表达式(C# 编程指南)MSDN
语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上。 借助于 LINQ,查询现在已是高级语言构造,就如同类、方法、事件等等。
对于编写查询的开发人员来说,LINQ 最明显的“语言集成”部分是查询表达式。 查询表达式是使用 C# 3.0 中引入的声明性查询语法编写的。 通过使用查询语法,您甚至可以使用最少的代码对数据源执行复杂的筛选、排序和分组操作。 您使用相同的基本查询表达式模式来查询和转换 SQL 数据库、ADO.NET 数据集、XML 文档和流以及 .NET 集合中的数据。
一个简单的例子
查询数组中的偶数,即num % 2 == 0
,使用以下代码。
第二种方法使用lamda表达式,不知道的可以先忽略。
int[] numbers = { 5, 10, 8, 3, 6, 12 };
//1. Query syntax
var numQuery1 = from num in numbers
where num % 2 == 0
orderby num
select num;
//2. Method syntax
var numQuerry2 = numbers.Where(num => num%2 == 0).OrderBy(num => num);
foreach (var i in numQuery1)
{
Console.Write("{0} ",i);
}
Console.WriteLine(" ");
foreach (var b in numQuerry2)
{
Console.Write("{0} ",b);
}
Console.ReadLine();
运行结果如图所示
orderby
后面可以加descending
和ascending
来指定是升序或者降序排列。
group分组的使用
增加如下类定义
class Student
{
public int ID { get; set; }
public string Name { get; set; }
public int Class { get; set; }
}
LINQ语句如下
List<Student> students = new List<Student>();
students.Add(new Student() {ID = 001,Name = "ZhangSan",Class = 1});
students.Add(new Student() {ID = 002,Name = "LiSiYu",Class = 4});
students.Add(new Student() {ID = 007,Name = "LaoWang",Class = 4});
students.Add(new Student() {ID = 010,Name = "ZhaoSi",Class = 2});
var studentsClass = from stu in students
group stu by stu.Class;
foreach (var c in studentsClass)
{
Console.WriteLine("Class {0}",c.Key);
foreach (var student in c)
{
Console.WriteLine(" {0} {1}",student.ID,student.Name);
}
}
Console.ReadLine();
运行结果如下图
可见studentsClass
是按照班级分组后的结果。
Join的使用
在上面的基础上增加类
class StudentHome
{
public string Name { get; set; }
public string Hometown { get; set; }
}
主函数部分如下
List<Student> students = new List<Student>();
students.Add(new Student() {ID = 001,Name = "ZhangSan",Class = 1});
students.Add(new Student() {ID = 002,Name = "LiSiYu",Class = 4});
students.Add(new Student() {ID = 007,Name = "LaoWang",Class = 4});
students.Add(new Student() {ID = 010,Name = "ZhaoSi",Class = 2});
List<StudentHome> studentHomes = new List<StudentHome>();
studentHomes.Add(new StudentHome() {Name = "LiSiYu",Hometown = "JiangSu"});
studentHomes.Add(new StudentHome() {Name = "LaoWang", Hometown = "HeBei"});
studentHomes.Add(new StudentHome() {Name = "WangWu",Hometown = "XinJiang"});
var studentsInfo = from student in students
join studentHome in studentHomes on student.Name equals studentHome.Name
select new {Name = student.Name, ID = student.ID, Hometown = studentHome.Hometown};
foreach (var studentInfo in studentsInfo)
{
Console.WriteLine("{0} {1} {2}", studentInfo.ID, studentInfo.Name, studentInfo.Hometown);
}
Console.ReadLine();
输出结果如下
可见linq类似于SQL语句中的join,将两个列表连接起来。on student.Name equals studentHome.Name
指定了两个列表的连接条件,select new {Name = student.Name, ID = student.ID, Hometown = studentHome.Hometown}
创建了一个新类型。
into的使用
into
可以将group
的结果暂时打包,后面的语句中可以使用该集合查询。例如下面的例子
var students = new List<Student>();
students.Add(new Student {ID = 001, Name = "ZhangSan", Class = 1});
students.Add(new Student {ID = 002, Name = "LiSiYu", Class = 4});
students.Add(new Student {ID = 007, Name = "LaoWang", Class = 4});
students.Add(new Student {ID = 010, Name = "ZhaoSi", Class = 2});
var studentsClass = from stu in students
group stu by stu.Class into stuClass
where stuClass.Count() >= 2
select new {Class = stuClass.Key, Number = stuClass.Count()};
foreach (var s in studentsClass)
{
Console.WriteLine("Class:{0} Number{1}", s.Class, s.Number);
}
这段程序就将分组的得到的结果存入stuClass
中,选择人数大于2的班级,创建一个包含班级名和人数的匿名类型。程序运行结果如下。
let的使用
let
相当于暂时定义一个变量,供后面查询使用,比如下面的代码
var studentHomes = new List<StudentHome>();
studentHomes.Add(new StudentHome {Name = "LiSiYu", Hometown = "JiangSu"});
studentHomes.Add(new StudentHome {Name = "LaoWang", Hometown = "HeBei"});
studentHomes.Add(new StudentHome {Name = "WangWu", Hometown = "XinJiang"});
var hometowns = from home in studentHomes
let BigHome = home.Hometown.ToUpper()
select BigHome;
foreach (var hometown in hometowns)
{
Console.WriteLine(hometown);
}
Console.ReadLine();
这里使用let
将家乡的大写定义为了BigHome
,这里也可以执行其他的复杂函数,程序运行结果如下
以上。