概述
标准运算查询符分三类:
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