C# Nut Shell 第九章 LINQ运算符

本文详细介绍了LINQ中的标准运算查询符,包括输入输出序列的运算符分类,筛选、映射、连接、排序、分组等操作的实现方式,以及各种集合运算符和生成集合的方法。通过具体示例,解析了不同查询符的功能和应用场景。
摘要由CSDN通过智能技术生成

概述

标准运算查询符分三类:

1.输入是序列,输出是序列

2.输入是集合,输出是单个元素或标量

3.没有输入,输出序列

int[] nums = { 1, 2, 3,4 };
List<Custom> customs = new List<Custom>
            {
                new Custom
                {
                    Num = 1,
                    FirstName = "zhang",
                    LastName = "bin"
                },
                new Custom
                {
                    Num = 2,
                    FirstName = "lbl",
                    LastName = "james"
                },
                new Custom
                {
                    Num = 3,
                    FirstName = "blet",
                    LastName = "kobe"
                },
            };

筛选

Where:返回满足条件的集合

Take:返回前count个元素,丢弃剩余的元素

Skip:跳过前count个元素,返回剩余的元素

TakeWhile:返回输入序列中元素,直到断言判断为false

SkipWhile:持续忽略输入序列中的元素,直到断言为false,返回剩余的元素

Distinct:返回一个没有重复元素的集合

筛选不会改变原来的集合元素

Where

1.满足断言

2.索引筛选

Where有2个重载方法,一种是只接受变量类型。还有一种是既接受变量类型,也接受位置。

3.对于字符串的查询一般有Contains(SQL中的Like),CompareTo


映射

Select:将输入中的每一个元素按照给定的Lambda表达式进行转换

SelectMany:将输入的每一个元素按照给定的Lambda表达式进行转换,并将嵌套的集合展平后连接在一起

Select

1.和Where一样,可以接受一个位置参数。仅支持本地查询

2.Select可以包含子查询,双重延迟查询

3.解释型查询用Select的嵌套查询效果好,而本地查询采用Join和GroupJoin效果更好

4.Select和let搭配很好

5.Select经常映射到匿名类型或者具体的类型

SelectMany

            //zhang,lbl,blet,blet
            var select = customs.Select(a => a.FirstName);
            //z,h,a,n,g,l,b,l...
            var selectMany = customs.SelectMany(a=>a.FirstName);

1.在查询表达式中药使用SelectMany需要使用2个from

2.在需要使用笛卡尔积的情况下用SelectMany(2个form),为了引进2个范围变量

3.SelectMany可以进行连接查询,和上面的2相似。这个连接是交叉连接,而不是左连接,右连接等。

4.SelectMany相当于把一个序列拆了一层后继续拆一层

            var select2 = from custom in customs
                          select custom.FirstName;
            var selectMany2 = from custom in customs
                              from sb in custom.FirstName
                              select sb;

5.SelectMany由于里面有2个from,相当于同时存在父元素和子元素,可以将2者结合起来。

6.还可以继续排序,排序的结果是全部平面化后,统一排序

            var selectMany2 = from custom in customs
                              from sb in custom.FirstName
                              orderby custom.FirstName,sb
                              select sb + " in " + custom.FirstName;

7.SelectMany从查询语法转化成流式语法的时候有一点麻烦,主要就是流式语法中只能表示一个变量,所以我们需要把这个变量变成一个匿名类型,而这个类型包含查询语法中的2个from的范围变量

            var select3 = customs.SelectMany(a => a.FirstName.Select(name => new { name, a }))
                .OrderBy(a => a.a.FirstName)
                .ThenBy(a => a.name)
                .Select(a => a.name + " in " + a.a.FirstName);

8.SelectMany可以实现交叉连接,非相等连接、内连接、左外连接

交叉连接

            var a = from num in nums
                    from custom in customs
                    select num + " " + custom.FirstName;

            var b = nums.SelectMany(num => customs.Select(custom => num + " " + custom.FirstName));

还可以加条件

            var c = from num in nums
                    from custom in customs
                    where num > custom.Num
                    select num + " " + custom.Num;

SelectMany在进行外连接的时候需要使用DefaultEmpty(),来表示如果拿到的数据为空有一个默认值。但是需要处理null的情况


连接

内连接:一般为等值连接,就是两个表中的某一列值相等,也可以为不等值连接。join可以进行等值连接,selectMany可以进行不等值连接。

外连接:左连接:以左边的表为准,右边空的填充空。右连接:以右边的表为准,左边空单位,填充空。全连接,交叉填充

交叉连接:笛卡尔积。

Join:使用查找规则对2个集合的元素进行匹配,返回平面的结果集

GroupJoin:同上,返回层次化结果集

Zip:同时依次枚举两个序列,对每一对元素执行指定的序列

Join和GroupJoin

1.Join和GroupJoin将2个输入序列连接为一个输出序列

2.from外部变量in外部集合 join内部变量in内部变量on外部键equals内部键表达式

3.Join和GroupJoin对本地内存集合的查询有更高的效率,但是对于交叉连接和非相等连接还是要用Select和SelectMany

4.查询数据库时应该使用Select

5.join内连接,只有equal两边的值相等的项可以加载进来,不存在的或者说多余的项不会加载。左项和右项顺序无关

6.基于多个键的连接,可以让左项和右项在多个属性上相等

on new {k1 = x.a, k2 = x.b}
equals new {k1 = y.a, k2 = y.b}

7.流式语法使用join

var c = customs.Join(nums, e => e.Num, d => d,
                (e, d) => new { e.FirstName,e.LastName,Num = d });

还可以进行排序

 var c = customs.Join(nums, e => e.Num, d => d,
                (e, d) => new { e,d }).OrderBy(x=>x.e.FirstName);

8.group的用法和join差不多,只不过生成的是层次化的结果,也就是说右项会被生成一个列表,需要2个循环才能遍历

9.可以直接在连接时放条件

var a = from q in customs
                    join p in nums.Where(f=>f>2) on q.Num equals p
                    into sb
                    select new { q.FirstName,sb};

Zip运算符

拉链式,同时枚举2个列表,不支持EF和L2S。枚举的数量为2个列表中的最小值


排序

1.OrderBy按照正常顺序排序

2.链式语法OrderBy,ThenBy

3.查询语法OrderBy a,b,c。注意:不能使用多个OrderBy,否则会按照最后一个OrderBY排序

4.在排序的时候可以指定比较器,但是在LINQ to SQL时,不支持比较器,如果要忽略大小写,可以直接指定全部大写再排序

5.Reverse:翻转顺序


分组

1.GroupBy可以根据条件分组

var a = nums.GroupBy(b => b>2);

2.有一个重载,可以在分组后进行再次运算

3.可以对分组后的数据进行排序,而这个排序是整体排序,不会对小组内的数据排序

4.查询语法

            var b = from r in nums
                    group r+1 by r > 2
                    into gr
                    orderby gr.Key descending
                    select gr;

5.

            var b = from r in nums
                    group r+1 by r > 2
                    into gr
                    //orderby gr.Key descending
                    where gr.Count() > 2
                    select gr;

集合运算符

Concat和Union

Concat和Union都可以将2个几个合并,可是Union可以去重

Intersect和Except

Intersect返回2个元素中共同元素

except返回存在于第一个,但是不存在于第二个的元素


转换方法

OfType和Case

1.可以让符合is规范的子类型转换成父类型(或者说是同类转换)成IEnumerable<T>类型

2.如果不符合OfType会丢弃该元素,Cast会抛出异常

ToArray,ToList,ToDictionary,ToLookup

ToArray:生成数组

ToList:生成泛型列表

ToDictionary:生成字典,但是需要制定一个键

ToLookup:和生成字典类似,但是可以相同的键,只不过那个键会包含多个值

AsEnumerable和AsQueryable

元素运算符

First,Last,Single

First:返回第一个元素,default是不抛出异常,返回null

single:返回唯一的元素,没有或者多余1个抛出异常

ElementAt

返回序列的第n个元素

DefaultEmpty

在输入序列为空时返回值包含一个default元素的序列,主要用来数显展平结果集的外连接


聚合方法

Count和LongCount

Count和LongCount会枚举序列,返回序列个数

Min和Max

返回最大值和最小值,可提供断言,当类型无法比较时,必须提供断言

Sum和Average

计算总数和平均值,可以提供断言。对类型又要求,必须是数值类型

Aggregate

用于实现自定义的独特聚合方法。无法在LINQ to SQL 和EF中使用。

比如可以实现累积。一般不使用,因为运算逻辑会出问题。简单的不需要用这个,用Select+sum+Average就可以搞定了,复杂的逻辑就会出错


量词运算符

Contains

判断是否包含,返回bool

Any

判断集合内元素是否有满足条件的元素,有一个就返回true,可以提供断言。如果没有断言,则集合有元素就返回true。

All

当序列中的所有元素都满足断言,则返回true

SequenceEqual

比较2个序列,当2个序列的元素都包含相同的元素,且顺序也相同,返回true,支持相等比较器


生成集合的方法

Empty:创建一个空序列

Repeat:创建一个含有重复元素的序列

Range:创建一个整数序列

            var a = Enumerable.Empty<int>(); //空,不是null
            var b = Enumerable.Range(6, 6); //6,7,8,9,10,11,12
            var c = Enumerable.Repeat("sb", 3);//sb,sb,sb

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值