LINQ语法全解

简介: LINQ语法全解

LINQ

LINQ指的是 Language Integrate Query

1. 初体验

分别使用静态方法,实例方法,查询语句进行LINQ查询

string[] strs = {
    "times", "get", "gives" ,"month"};
//使用静态方法
IEnumerable<string> strEnum = 
    System.Linq.Enumerable.Where(strs, n => n.Length >= 4);
foreach (var item in strEnum)
{
   
    Console.WriteLine(item);
}
Console.WriteLine("---------------");
//使用实例方法
IEnumerable<string> strE2 = strs.Where(n => n.Length > 4).Skip(1);
foreach (var item in strE2)
{
   
    Console.WriteLine(item);
}
Console.WriteLine("---------------");
//使用查询语句
IEnumerable<string> worEnu = from n in strs where n.Contains('e') select n;
foreach (var item in worEnu)
{
   
    Console.WriteLine(item);
}
//times
//gives
//month
//---------------
//gives
//month
//---------------
//times
//get
//gives

1.1 流式语句

流式语句,就是一连串的条件进行限定。流式方法和静态方法可以相互转换。

string[] strs = {
    "time", "get", "gives" ,"month","Tom","Jerrys"};
//流式方法
IEnumerable<string> strEnu = strs.Where(n=>n.Length>3)
    .Where(n=>n.Contains("e"))
    .OrderBy(n => n.Length);
foreach (var item in strEnu)
{
   
    Console.WriteLine(item);
}
Console.WriteLine("-------------");
//等价于以下的静态方法
IEnumerable<string> strWhereEnu = Enumerable.Where(strs, n => n.Length > 3);
IEnumerable<string> strWhereCon = Enumerable.Where(strWhereEnu, n => n.Contains('e'));
IOrderedEnumerable<string> strOrderEnu = Enumerable.OrderBy(strWhereCon, n => n.Length);
foreach (var item in strOrderEnu)
{
   
    Console.WriteLine(item);
}
//time
//gives
//Jerrys
//-------------
//time
//gives
//Jerrys

1.2 序列相关部分运算符

  • Take 运算符:Take 是拿出序列的几个数

  • Skip 运算符:Skip 是跳过序列的前几个数

  • Reverse 运算符:Reverse 是将序列反转
string[] strs = {
    "time", "get", "gives" ,"month","Tom","Jerrys"};
foreach (var item in strs.Take(3))
{
   
    Console.WriteLine(item);
}
Console.WriteLine("--------------");
foreach (var item in strs.Skip(3))
{
   
    Console.WriteLine(item);
}
Console.WriteLine("--------------");
foreach (var item in strs.Reverse())
{
   
    Console.WriteLine(item);
}
//time
//get
//gives
--------------
//month
//Tom
//Jerrys
--------------
//Jerrys
//Tom
//month
//gives
//get
//time
  • Contcat 运算符:连接两个字符串,有重复元素也连接在一起
  • Union 元算符:联合两个字符串,有重复元素就省略重复的元素
string[] strs = {
    "time", "get" ,"Jim"};
string[] strtemp = {
    "month", "Tom", "Jim" };

foreach (var item in strs.Concat(strtemp))
{
   
    Console.WriteLine(item);
}
Console.WriteLine("------------------");
foreach (var item in strs.Union(strtemp))
{
   
    Console.WriteLine(item);
}
//time
//get
//Jim
//month
//Tom
//Jim
//------------------
//time
//get
//Jim
//month
//Tom

1.3 查询相关部分运算符

  • First,获取序列第一个元素
  • Last,获取序列最后一个元素
  • ElementAt,获取序列的某一个索引元素
  • Min,获取序列最小值
  • Count,获取序列元素的个数
  • Any,是否有元素满足某个条件,如果有一个满足就返回true
  • All,与Any相反,但是这个必须要有一个判断条件
string[] strs = {
    "time", "get", "gives" ,"month","Tom","Jerrys"};
Console.WriteLine(strs.First());
Console.WriteLine(strs.Last());
Console.WriteLine(strs.ElementAt(2));
Console.WriteLine(strs.Min());
Console.WriteLine(strs.Count());
Console.WriteLine(strs.Any());
Console.WriteLine(strs.Any(n=>n.Length>5));
Console.WriteLine(strs.All(n=>n.Length>4));
//time
//Jerrys
//gives
//get
//6
//True
//True
//False

2.查询表达式

  • 延迟执行特性:查询语句构造完成后, 并不会立即执行,而是等到foreach里面才执行,在这执行之前,如果新增了元素,那么元素在foreach里也或生效。
  • 临时使用外部变量:当foreach前改变lambda表达式里面的外部变量值,那么构造的语句也会根据外部变量改变而改变
//延迟执行特性
List<int> list = new List<int> {
    1 };
IEnumerable<int> intEnu = list.Select(n => n * 10);
list.Add(2);
foreach (var item in intEnu)
{
   
    Console.WriteLine(item);
}
//10
//20
//临时修改外部变量
List<int> list = new List<int> {
    1,2};
int mul = 10;
IEnumerable<int> intEnu = list.Select(n => n * mul);
foreach (var item in intEnu)
{
   
    Console.WriteLine(item);
}
Console.WriteLine("-----------------");
//临时修改外部变量
mul = 100;
foreach (var item in intEnu)
{
   
    Console.WriteLine(item);
}
//10
//20
//-----------------
//100
//200

3. 子查询

就是把一个LINQ作为另一个LINQ的输入

4. into 关键字

使用into关键字,将原始查询重命名,其他都是一样的,性能也不变。

另外,into关键字只能在Select和Group后面添加。

string[] names = {
    "Tom", "Jerry", "kate", "Lucy", "Micky" };

IEnumerable<string> strName =
    from n in names
    where names.Length > 3
    select n.Replace('y', 'Y')
    into na
    where na.Length > 3
    select na;

foreach (var item in strName)
{
   
    Console.WriteLine(item);
}
//JerrY
//kate
//LucY
//MickY

5. 使用LINQ进行对象初始化

5.1 对象类型

需要声明定义一个对象类,然后使用select 配合new关键字进行对象初始化。

string[] names = {
    "Tom", "Jerry", "kate", "Lucy", "Micky","li" };
IEnumerable<Person> query =
    from p in names
    select new Person
    {
   
        name = p,
        liName = p.ToLower()
    };

foreach (var item in query)
{
   
    Console.WriteLine(item.name+","+item.liName);
}
Console.WriteLine("---------------------");
//继续使用上面的查询作为输入
IEnumerable<string> strName =
    from n in query
    where n.name.Length > 2
    orderby n.name.Length descending
    select n.name + "," + n.liName;

foreach (var item in strName)
{
   
    Console.WriteLine(item);
}
//输出
//Tom,tom
//Jerry,jerry
//kate,kate
//Lucy,lucy
//Micky,micky
//li,li
//---------------------
//Jerry,jerry
//Micky,micky
//kate,kate
//Lucy,lucy
//Tom,tom

5.2 匿名类型

可以不用声明定义一个对象,直接使用new,然后直接赋值即可

string[] names = {
    "Tom", "Jerry", "kate", "Lucy", "Micky", "li" };

var query =
    from n in names
    select new
    {
   
        name = n,
        liName = n.ToLower()
    };

foreach (var item in query)
{
   
    Console.WriteLine(item.liName+","+item.name);
}

Console.WriteLine("--------------");

IEnumerable<string> strName =
    from n in query
    where n.name.Length > 2
    orderby n.name.Length descending
    select n.name + "," + n.liName;

foreach (var item in strName)
{
   
    Console.WriteLine(item);
}
//输出
tom,Tom
jerry,Jerry
kate,kate
lucy,Lucy
micky,Micky
li,li
--------------
Jerry,jerry
Micky,micky
kate,kate
Lucy,lucy
Tom,tom

使用两个数组,分别取出两个数组元素的索引,进行比较,然后拼接成一个匿名对象,进行输出。

string[] names = {
    "Tom", "Jerry", "kate", "Lucy", "Micky", "li" ,"zh"};
int[] ages = {
    10, 20, 50, 12, 45, 20 };

var indexedItems = names.Select((value, index) => new {
    Index = index, Value = value });

var dicar =
    from n in names.Select((value, index) => new {
    Index = index, Value = value })
    join a in ages.Select((value, index) => new {
    Index = index, Value = value }) on n.Index equals a.Index
    select new
    {
   
        name = n.Value,
        age = a.Value
    };

foreach (var item in dicar)
{
   
    Console.WriteLine($"{item.name},{item.age}");
}
//输出
Tom,10
Jerry,20
kate,50
Lucy,12
Micky,45
li,20

6. let 关键字

let关键字作用是,能够在LINQ中使用一个临时变量来储存临时结果,然后对这个临时结果进行处理。

string[] names = {
    "Tom", "Jerry", "kate", "Lucy", "Micky", "li", "zh" };
var query =
    from n in names
    let temp = n.Replace('y', 'Y')
    where temp.Length > 2
    orderby temp descending
    select temp;

foreach (var item in query)
{
   
    Console.WriteLine(item);
}
//输出
Tom
MickY
LucY
kate
JerrY
目录
相关文章
|
7月前
|
SQL 开发框架 .NET
EntityFramework数据持久化复习资料5、LINQ概述与应用(超终点)
EntityFramework数据持久化复习资料5、LINQ概述与应用(超终点)
64 0
|
7月前
|
SQL 存储 开发框架
EntityFramework数据持久化复习资料4、Lambda表达式的使用(重点内容)
EntityFramework数据持久化复习资料4、Lambda表达式的使用(重点内容)
53 0
|
开发框架 搜索推荐 .NET
推荐一个C#全文搜索支持Linq表达式的开源项目
一个IQueryable与IEnumerable扩展方法库
149 0
推荐一个C#全文搜索支持Linq表达式的开源项目
|
XML .NET 数据库