语言集成查询 (Language Integrated Query) 是一系列直接将查询功能集成到 C# 语言的技术统称,用于在所有基于.NET平台的变成语言中更加直接地声明跨越、过滤和投射操作的一种方式,标准查询操作允许查询作用于所有基于IEnumerable接口的源。

LINQ简单查询

using System;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
int[] scores = new int[] { 90, 91, 59, 55, 80 };
var x = from score in scores where score >= 60 orderby score descending select score;
foreach( var s in x)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
}
}

C#的LINQ select查询、where过滤、group分组、join关联_匿名类型

函数

案例一

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<int> num1 = new List<int> { 1, 2, 3, 4, 5 };
List<int> num2 = new List<int> { 17, 18, 19, 20 };
var concat = num1.Concat(num2);
double average = concat.Average();
Console.WriteLine(average);
Console.ReadLine();
}
}
}

案例二

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
int[] scores = new int[] { 81, 90, 60, 55, 100 };
var c = from score in scores where score >= 60 select score;
Console.WriteLine(c.Count());
Console.WriteLine(c.Max());
Console.ReadLine();
}
}
}

LINQ子句

where子句

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>()
{
new Student() {name="张三", age=22, telephone="1234567890"},
new Student() {name="张四", age=23, telephone="1234567891"},
new Student() {name="王五", age=21, telephone="1234567892"}
};

var query = from student in students
where student.name.Contains("张")
&& student.age > 21
select student;
foreach (var s in query)
{
Console.WriteLine("{0} - {1} - {2}", s.name, s.age, s.telephone);
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public string telephone { get; set; }
}
}

C#的LINQ select查询、where过滤、group分组、join关联_.net_02

orderby 子句

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>()
{
new Student() {name="张三", age=22, telephone="1234567890"},
new Student() {name="张四", age=23, telephone="1234567891"},
new Student() {name="王五", age=21, telephone="1234567892"}
};

var query = from student in students
where student.name.Contains("张")
&& student.age > 21
orderby student.age descending
select student;
foreach (var s in query)
{
Console.WriteLine("{0} - {1} - {2}", s.name, s.age, s.telephone);
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public string telephone { get; set; }
}
}

C#的LINQ select查询、where过滤、group分组、join关联_c#_03

select 子句

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>()
{
new Student() {name="张三", age=22, telephone="1234567890"},
new Student() {name="张四", age=23, telephone="1234567891"},
new Student() {name="王五", age=21, telephone="1234567892"}
};
// 替换
var query1 = from student in students
orderby student.age descending
select student.name.Replace("张四", "李四");
// 自定义方法
var query2 = from student in students
orderby student.age descending
select MyFunc(student.name);
// 匿名类型
var query3 = from student in students
orderby student.age descending
select new { name=student.name + "OK!", age=student.age+10};
// 对查询结果投影
var query4 = from student in students
orderby student.age descending
select new Student{ name = student.name, age = 25, telephone=""};
foreach (var s in query1)
{
Console.WriteLine(s);
}
foreach (var s in query2)
{
Console.WriteLine(s);
}
foreach (var s in query3)
{
Console.WriteLine(s.name + " " + s.age);
}
foreach (var s in query4)
{
Console.WriteLine(s.name + " " + s.age);
}
static string MyFunc(string s)
{
return s + "好!";
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public string telephone { get; set; }
}
}

C#的LINQ select查询、where过滤、group分组、join关联_匿名类型_04

多个from子句

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>()
{
new Student() {name="张三", age=22, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{99, 100} },
new Student() {name="张四", age=23, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{99, 100}},
new Student() {name="王五", age=21, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{99, 100}}
};
var query1 = from student in students
from add in student.addr
from score in student.scores
orderby student.age descending
select new {newName = student.name, newAddr = add, nawSocre = score};
foreach(var s in query1)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public List<string> addr { get; set; }
public List<int> scores { get; set; }
}
}

LINQ中的from子句中引用的数据源类型必须是IEnumerable、IEnumerable或一种派生类型(如IQueryable)类型。

如果一个数据源里面又包含一个或多个集合列表,可以使用复合的from子句查询。

C#的LINQ select查询、where过滤、group分组、join关联_linq_05

group子句

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>()
{
new Student() {name="张三", age=22, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{99, 100} },
new Student() {name="张四", age=23, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{99, 100}},
new Student() {name="王五", age=21, addr= new List<string>(){ "中国", "北京"}, scores=new List<int>{99, 100}}
};
var query = from student in students
group student by student.addr[1];
foreach(var group in query)
{
Console.WriteLine(group.Key);
foreach(var s in group)
{
Console.WriteLine(" "+s.name);
}
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public List<string> addr { get; set; }
public List<int> scores { get; set; }
}
}

此例使用双层循环根据省份进行分组。group查询产生的类型是IGrouping<TKey, TElement>类型,实质是列表的列表。

C#的LINQ select查询、where过滤、group分组、join关联_linq_06

into子句

into子用于group、select、join子句中充当其结果引用的临时标识符。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>()
{
new Student() {name="张三", age=22, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{99, 100} },
new Student() {name="张四", age=23, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{90, 80}},
new Student() {name="王五", age=21, addr= new List<string>(){ "中国", "北京"}, scores=new List<int>{99, 80}}
};
var query = from student in students
group student by student.scores[1] into student_group
orderby student_group.Key descending
select student_group;
foreach(var group in query)
{
Console.WriteLine(group.Key);
foreach(var s in group)
{
Console.WriteLine(" "+s.name);
}
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public List<string> addr { get; set; }
public List<int> scores { get; set; }
}
}

C#的LINQ select查询、where过滤、group分组、join关联_linq_07

let 子句

let子句产生一个用于存储查询表达式中的子表达式查询结果的范围变量。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>()
{
new Student() {name="张三", age=22, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{99, 100} },
new Student() {name="张四", age=23, addr= new List<string>(){ "中国", "山东"}, scores=new List<int>{90, 80}},
new Student() {name="王五", age=21, addr= new List<string>(){ "中国", "北京"}, scores=new List<int>{99, 80}}
};
var query = from student in students let c = student.addr
where c[0]=="中国" && c[1]=="山东"
select student;
// 等效where
var query1 = from student in students
where student.addr[0] == "中国" && student.addr[1] == "山东"
select student;
foreach (var s in query)
{
Console.WriteLine(s.name);
}
foreach (var s in query1)
{
Console.WriteLine(s.name);
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public List<string> addr { get; set; }
public List<int> scores { get; set; }
}
}

C#的LINQ select查询、where过滤、group分组、join关联_匿名类型_08

join子句

join子句可以关联两个数据源,使用equals关键字进行比较两个数据源中的某个属性,而不是用“==”。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<Student> students1 = new List<Student>()
{
new Student() {name="张三", age=22},
new Student() {name="张四", age=23},
new Student() {name="王五", age=21}
};
List<Student> students2 = new List<Student>()
{
new Student() {name="张三", scores=new List<int>{99, 100}},
new Student() {name="张四", scores=new List<int>{90, 80}},
new Student() {name="王五", scores=new List<int>{99, 80}}
};
var query = from student1 in students1
join student2 in students2
on student1.name equals student2.name
select new Student {name=student1.name,
age=student1.age, scores=student2.scores};
foreach (var s in query)
{
Console.WriteLine(string.Format("Name:{0}, Age:{1}, Scores:{2}",
s.name, s.age, s.scores[0]));
}
Console.ReadLine();
}
}



public class Student
{
public string name { get; set; }
public int age { get; set; }
public List<int> scores { get; set; }
}
}

C#的LINQ select查询、where过滤、group分组、join关联_匿名类型_09

参考

​https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/​