标准查询操作符
本文章是我最近学习Linq的一些示例,分享给和我一样刚开始接触Linq的朋友们作为一个参考,因为是初学,肯定有很多不足,因此希望大家友善提醒,切勿针锋相对,我会及时改正的~~
目录01 投影操作符(Select,SelectMany)
02 限制操作符(Where)
03 排序操作符(OrderBy,OrderByDescending,ThenBy,ThenByDescending,Reverse)
04 联接操作符(join,GroupJoin)
05 分组操作符(GroupBy)
06 串联操作符(Concat)
07 聚合操作符(Aggregate,Average,Count,LongCount,Max,Min,Sum)
08 集合操作符(Distinct,Union,Intersect,Except)
09 生成操作符(Empty,Range,Repeat)
10 转换操作符(Cast,OfType,ToArray,ToDictionary,ToList,ToLookup)
11 元素操作符(DefaultIfEmpty,ElementAt,ElementAtOrDefault,First,Last,FirstOrDefault,LastOrDefault,Single,SingleOrDefault)
12 相等操作符(SequenceEqual)
13 量词操作符(All,Any)
14 分割操作符(Skip,SkipWhile,Take,TakeWhile)
01.投影操作符(Select,SelectMany)
(1)Select操作符对单个序列或者集合中的值进行投影,可以控制从序列中返回指定的列.
方法语法:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
User[] users = new User[]{
new User(){ Id = 1 , FirstName = " Huang " , LastName = " Cong " , Age = 12 },
new User(){ Id = 2 , FirstName = " Yang " , LastName = " Qiu " , Age = 22 },
new User(){ Id = 3 , FirstName = " Cai " , LastName = " Zheng " , Age = 18 },
new User(){ Id = 4 , FirstName = " Huang " , LastName = " Chao " , Age = 32 },
new User(){ Id = 5 , FirstName = " Teng " , LastName = " Jie " , Age = 12 },
new User(){ Id = 6 , FirstName = " Liang " , LastName = " Zhi " , Age = 8 }
};
// 使用Select操作符进行投影,对序列只返回First一个列
var query = users.Select(u => new { u.FirstName });
// 输出
foreach (var q in query)
Console.WriteLine(q.FirstName);
}
}
class User
{
public int Id { get ; set ; }
public string FirstName { get ; set ; }
public string LastName { get ; set ; }
public int Age { get ; set ; }
public override string ToString()
{
return String.Format( " Id:{0}\tFirstName:{1}\tLastName:{2}\tAge:{3} " , this .Id, this .FirstName, this .LastName, this .Age);
}
}
}
(2)SelectMany操作符提供了将多个from子句组合起来的功能,它将每个对象的结果合并成单个序列.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
Names[] owners =
{ new Names { FirstName = " Scott, Chris " ,
Pets = new List < string > { " Yukon " , " Fido " }},
new Names { FirstName = " Jason, Steve " ,
Pets = new List < string > { " Killer " , " Fluffy " }},
new Names { FirstName = " John, Joe " ,
Pets = new List < string > { " Spike " , " Tinkerbell " }}};
// 使用SelectMany操作符将每个对象的Pets组合成一个序列
var query = owners.SelectMany(owner => owner.Pets);
// 对组合好的Pets进行输出
foreach (var q in query)
Console.WriteLine(q);
}
}
class Names
{
public string FirstName { get ; set ; }
public List < string > Pets { get ; set ; }
}
}
运行结果:
02.限制操作符(Where)
(1)Where是限制操作符,可以对序列中的值进行过滤.Where操作符不启动查询的执行.但开始对对象进行迭代的时候才将过滤器应用到数据上.
方法语法:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < string > names = new List < string > ();
names.Add( " Scott " );
names.Add( " Dave " );
names.Add( " Dave " );
names.Add( " Steve " );
names.Add( " Joe " );
// 使用Where操作符查询序列中以S开头的元素
var query = names.Where(n => n.StartsWith( " S " ));
// 对组合好的Pets进行输出
foreach (var q in query)
Console.WriteLine(q);
}
}
}
查询语法:
运行结果:
03 排序操作符(OrderBy,OrderByDescending,ThenBy,ThenByDescending,Reverse)
(1)OrderBy/OrderByDescending操作符能将序列中的返回值按照升序/降序的顺序进行排列.
方法语法:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < string > names = new List < string > ();
names.Add( " Scott " );
names.Add( " Dave " );
names.Add( " Dave " );
names.Add( " Steve " );
names.Add( " Joe " );
// 使用OrderBy操作符对序列进行排序
var query = names.Select(n => n).OrderBy(n => n);
Console.WriteLine( " ----------------------OrderBy排序---------------------- " );
foreach (var q in query)
Console.WriteLine(q);
// 使用OrderByDescending操作符对序列进行倒序
query = names.Select(n => n).OrderByDescending(n => n);
Console.WriteLine( " ----------------------OrderByDescending排序---------------------- " );
foreach (var q in query)
Console.WriteLine(q);
}
}
}
查询语法:
var query = from n in names orderby n select n;
//倒 序
query = from n in names orderby n descending select n;
运行结果:
(2)ThenBy/ThenByDescending操作符可按照次关键对序列进行升序/降序排列.
方法语法:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public string Name { get ; set ; }
public int Age { get ; set ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
users.Add( new User() { Name = " Scott " , Age = 12 });
users.Add( new User() { Name = " Scott " , Age = 22 });
users.Add( new User() { Name = " Doe " , Age = 11 });
users.Add( new User() { Name = " Doe " , Age = 8 });
users.Add( new User() { Name = " Scott " , Age = 18 });
users.Add( new User() { Name = " Doe " , Age = 24 });
// 使用ThenBy操作符对序列再次进行排序
var query = users.Select(u => u).OrderBy(u => u.Name).ThenBy(u => u.Age);
Console.WriteLine( " ----------------------ThenBy排序---------------------- " );
foreach (var q in query)
Console.WriteLine( " Name:{0}\tAge:{1} " , q.Name, q.Age);
// 使用ThenByDescending操作符对序列再次进行排序
query = users.Select(u => u).OrderBy(u => u.Name).ThenByDescending(u => u.Age);
Console.WriteLine( " ----------------------ThenByDescending排序---------------------- " );
foreach (var q in query)
Console.WriteLine( " Name:{0}\tAge:{1} " , q.Name, q.Age);
}
}
}
查询语法:
var query = from u in users orderby u.Name, u.Age select u;
// 倒序
query = (from u in users orderby u.Name select u).ThenByDescending(u => u.Age);
运行结果:
(3)Reverse操作符只是简单的把数据源中的数据按照相反的顺序返回.(需要注意的是:Reverse在LINQ To SQL中是不支持的).
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < string > names = new List < string > ();
names.Add( " Scott " );
names.Add( " Dave " );
names.Add( " Dave " );
names.Add( " Steve " );
names.Add( " Joe " );
// 使用Reverse操作符对序列进行逆序排列
names.Reverse();
foreach (var q in names)
Console.WriteLine(q);
}
}
}
运行结果:
04 联接操作符(join,GroupJoin)
(1)join操作符类似于T-SQL中的inner join,它可以将一个数据源与另一个数据源想联接,根据两个数据源中相等的值进行匹配.
方法语法:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public string Name { set ; get ; }
public int RoleId { set ; get ; }
}
class Role
{
public int Id { get ; set ; }
public string Name { get ; set ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
List < Role > roles = new List < Role > ();
roles.Add( new Role() { Id = 1 , Name = " Admin " });
roles.Add( new Role() { Id = 2 , Name = " Guest " });
users.Add( new User { RoleId = 1 , Name = " Scott " });
users.Add( new User { RoleId = 1 , Name = " Dave " });
users.Add( new User { RoleId = 2 , Name = " Steve " });
users.Add( new User { RoleId = 2 , Name = " Joe " });
// 查询出ID为1的角色下的所有用户
var query = users.Join(roles, u => u.RoleId, r => r.Id, (u, r) => new { UserName = u.Name, RoleId = r.Id, RoleName = r.Name }).Where(q => q.RoleId == 1 );
foreach (var q in query)
Console.WriteLine( " UserName:{0}\tRoleId:{1}\tRoleName:{2} " , q.UserName, q.RoleId, q.RoleName);
}
}
}
查询语法:
join u in users on r.Id equals u.RoleId
where r.Id == 1
select new { RoleId = r.Id, RoleName = r.Name, UserName = u.Name };
运行结果:
(2)GroupJoin操作符类似于T-SQL中的INNER JOIN, LEFT OUTER JOIN,返回的是一个层级的结果集
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public string Name { set ; get ; }
public int RoleId { set ; get ; }
}
class Role
{
public int Id { get ; set ; }
public string Name { get ; set ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
List < Role > roles = new List < Role > ();
roles.Add( new Role() { Id = 1 , Name = " Admin " });
roles.Add( new Role() { Id = 2 , Name = " Guest " });
users.Add( new User { RoleId = 1 , Name = " Scott " });
users.Add( new User { RoleId = 1 , Name = " Dave " });
users.Add( new User { RoleId = 2 , Name = " Steve " });
users.Add( new User { RoleId = 2 , Name = " Joe " });
// 查询所有角色下的用户
var query = roles.GroupJoin(users, r => r.Id, u => u.RoleId, (role, user) => new { RoleId = role.Id, RoleName = role.Name, Users = user.Where(u => u.RoleId == role.Id) });
foreach (var role in query)
{
Console.WriteLine( " RoleId:{0} RoleName:{1} " , role.RoleId, role.RoleName);
foreach (var user in role.Users)
{
Console.WriteLine( " " + user.Name);
}
}
}
}
}
运行结果:
05 分组操作符(GroupBy)
(1)GroupBy分组操作符是根据一个指定的特定值将序列中的值或元素进行分组.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public string Name { set ; get ; }
public int RoleId { set ; get ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
users.Add( new User { RoleId = 1 , Name = " Scott " });
users.Add( new User { RoleId = 1 , Name = " Dave " });
users.Add( new User { RoleId = 2 , Name = " Steve " });
users.Add( new User { RoleId = 2 , Name = " Joe " });
// 按RoleId对所有用户进行分组
var query = users.GroupBy(u => u.RoleId);
foreach (var o in query)
{
Console.WriteLine( " RoleId:{0}: " , o.Key);
foreach (var user in o)
{
Console.WriteLine( " Name:{0} " , user.Name);
}
}
}
}
}
运行结果:
06 串联操作符(Concat)
(1)Concat操作符可以将两个对象联接在一起
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public string Name { set ; get ; }
public int RoleId { set ; get ; }
}
class Role
{
public int Id { get ; set ; }
public string Name { get ; set ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
List < Role > roles = new List < Role > ();
roles.Add( new Role() { Id = 1 , Name = " Admin " });
roles.Add( new Role() { Id = 2 , Name = " Guest " });
users.Add( new User { RoleId = 1 , Name = " Scott " });
users.Add( new User { RoleId = 1 , Name = " Dave " });
users.Add( new User { RoleId = 2 , Name = " Steve " });
users.Add( new User { RoleId = 2 , Name = " Joe " });
// 按所有的用户名称和角色名称联接起来
var query = users.Select(u => u.Name).Concat(roles.Select(r => r.Name));
foreach (var q in query)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
07 聚合操作符(Aggregate,Average,Count,LongCount,Max,Min,Sum)
(1)聚合函数是在序列上执行特定的运算后返回单个值.共有7个聚合查询操作符:
Aggregate:将序列中的值进行累积并返回结果.
Average:计算一个数值序列的平均值.
Count,LongCount:计算一个集合中元素的个数.但是前者返回的是Int32类型的值,后者为Int64
Max,Min:分别是返回序列中的最大值和最小值
Sum:返回集合中数值的总和
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public string Name { set ; get ; }
public int Age { set ; get ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
users.Add( new User { Age = 12 , Name = " Scott " });
users.Add( new User { Age = 22 , Name = " Dave " });
users.Add( new User { Age = 18 , Name = " Steve " });
users.Add( new User { Age = 24 , Name = " Joe " });
string Names = " Scott,Dave,Steve,Joe " ;
string [] name = Names.Split( ' , ' );
Console.WriteLine( " 使用Aggregate将名称组合起来: " );
string query1 = name.Aggregate((n, next) => n + " " + next);
Console.WriteLine(query1);
Console.WriteLine( " ------------------------------------------------ " );
Console.WriteLine( " 使用Average求出所有用户年龄的平均数: " );
var query2 = users.Select(u => u.Age).Average();
Console.WriteLine(query2);
Console.WriteLine( " ------------------------------------------------ " );
Console.WriteLine( " 使用Count求出总共有多少个用户: " );
var query3 = users.Count();
Console.WriteLine(query3);
Console.WriteLine( " ------------------------------------------------ " );
Console.WriteLine( " 使用LongCount求出所有用户年龄的平均数: " );
var query4 = users.LongCount();
Console.WriteLine(query4);
Console.WriteLine( " ------------------------------------------------ " );
Console.WriteLine( " 使用Max求出所有用户年龄的最大数: " );
var query5 = users.Select(u => u.Age).Max();
Console.WriteLine(query5);
Console.WriteLine( " ------------------------------------------------ " );
Console.WriteLine( " 使用Min求出所有用户年龄的最小数: " );
var query6 = users.Select(u => u.Age).Min();
Console.WriteLine(query6);
Console.WriteLine( " ------------------------------------------------ " );
Console.WriteLine( " 使用Sum求出所有用户年龄的总和: " );
var query7 = users.Select(u => u.Age).Sum();
Console.WriteLine(query7);
Console.WriteLine( " ------------------------------------------------ " );
}
}
}
运行结果:
08 集合操作符(Distinct,Union,Intersect,Except)
(1)Distinct操作符可以删除集合中重复的值,并返回该集合中不相同的元素.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
int [] numbers = new int [] { 1 , 1 , 1 , 2 , 3 , 4 , 5 , 5 };
// 使用Distinct将数组中重复的元素删除掉
var query = numbers.Distinct();
foreach (var q in query)
{
Console.WriteLine(query);
}
}
}
}
![2010122914195041.jpg](https://i-blog.csdnimg.cn/blog_migrate/126bca9dc27aa30a84c33c7ef03f286d.jpeg)
(2)Union操作符可以取两个集合的互不相同的所有数值.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
int [] numbers1 = new int [] { 1 , 1 , 1 , 2 , 3 , 4 , 5 , 5 };
int [] numbers2 = new int [] { 2 , 2 , 3 , 4 , 4 , 5 , 6 , 7 };
// 使用Union将两个数组中重复的元素删除掉并且合并起来
var query = numbers1.Union(numbers2);
foreach (var q in query)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
(3)Intersect操作符可以返回两个序列的交集.也就是返回同时存在于2个序列中的值.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
int [] numbers1 = new int [] { 1 , 1 , 1 , 2 , 3 , 4 , 5 , 5 };
int [] numbers2 = new int [] { 2 , 2 , 3 , 4 , 4 , 5 , 6 , 7 };
// 使用Intersect求两个集合的交集
var query = numbers1.Intersect(numbers2);
foreach (var q in query)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
(4)Except操作符可以返回两个序列中不同的值.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
int [] numbers1 = new int [] { 1 , 1 , 1 , 2 , 3 , 4 , 5 , 5 };
int [] numbers2 = new int [] { 2 , 2 , 3 , 4 , 4 , 5 , 6 , 7 };
// 使用Except求numbers1中有但是numbers2中没有的值
var query = numbers1.Except(numbers2);
foreach (var q in query)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
09 生成操作符(Empty,Range,Repeat)
(1)Empty操作符可以返回一个指定类型的空集,通常用来作为聚合操作符的种子值.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
int [] numbers1 = new int [] { 1 , 2 , 3 , 4 , 5 };
int [] numbers2 = new int [] { 4 , 5 , 6 , 7 };
List < int [] > numbers = new List < int [] > { numbers1, numbers2 };
// 创建一个空int类型的集合
var empty = Enumerable.Empty < int > ();
// 求numbers1和numbers2中有7这个元素的集合,并输出具备条件的集合
var query = numbers.Aggregate(empty, (n, next) => next.Contains( 7 ) ? n.Union(next) : n);
foreach (var q in query)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
(2)Range操作符可以创建一个连续数字序列的集合.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
Console.WriteLine( " 创建一个1~6的数值集合 " );
var numbers = Enumerable.Range( 1 , 6 );
foreach (var q in numbers)
{
Console.WriteLine(q);
}
Console.WriteLine( " -------------------------------------- " );
Console.WriteLine( " 倒序 " );
var query = numbers.Reverse();
foreach (var q in query)
{
Console.WriteLine(q);
}
Console.WriteLine( " -------------------------------------- " );
Console.WriteLine( " 输出1~6的偶数 " );
query = numbers.Where(u => u % 2 == 0 );
foreach (var q in query)
{
Console.WriteLine(q);
}
Console.WriteLine( " -------------------------------------- " );
}
}
}
运行结果:
(3)Repeat操作符可以创建一个单值序列,可自定义重复的次数.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 将Good!重复6次
var numbers = Enumerable.Repeat( " Good! " , 6 );
foreach (var q in numbers)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
10 转换操作符(Cast,OfType,ToArray,ToList,ToLookup)
(1)Cast操作符将查询可以将IEnumerable中的元素转换为指定的类型.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
ArrayList names = new ArrayList();
names.Add( " Scott " );
names.Add( " Dave " );
names.Add( " Steve " );
names.Add( " Joe " );
// ArrayList不实现IEnumberable(Of T),不可以使用标准查询操作符,
// 但是通过Cast转换之后就可以使用了
var query = names.Cast < string > ().Select(u => u);
foreach (var q in query)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
(2)OfType操作符可以对一个序列进行指定类型的过滤.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
ArrayList names = new ArrayList();
names.Add( " Scott " );
names.Add( 1 );
names.Add( " Dave " );
names.Add( 2 );
names.Add( " Steve " );
names.Add( 3 );
names.Add( " Joe " );
// 通过OfType可以过滤只能转换为int类型的元素
var query = names.OfType < int > ().Select(u => u);
foreach (var q in query)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
(3)ToArray/ToList操作符可以分别可以将序列创建为一个数组或者List<T>对象.需要注意的是进行转换时会强制查询立即执行,也就意味着查询将于源数据断开联系.得到的序列为新创建的数组或List<T>.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < string > names = new List < string > ();
names.Add( " Scott " );
names.Add( " Dave " );
// 转换为Array或者List
var query1 = names.Select(u => u).ToArray();
var query2 = names.Select(u => u).ToList();
Console.WriteLine( " ToArray: " );
foreach (var q in query1) { Console.WriteLine( " " + q); }
Console.WriteLine( " ToList: " );
foreach (var q in query2) { Console.WriteLine( " " + q); }
Console.WriteLine( " --------------------------------------------- " );
// 添加新元素
names.Add( " Steve " );
names.Add( " Joe " );
// 再次输出,但是并没有后面添加的元素,说明查询与源数据已断开联系
Console.WriteLine( " ToArray: " );
foreach (var q in query1) { Console.WriteLine( " " + q); }
Console.WriteLine( " ToList: " );
foreach (var q in query2) { Console.WriteLine( " " + q); }
}
}
}
运行结果:
(4)ToDictionary/ToLookUp可以将序列分别转换为一对一的Dictionary<T Key,T Value>字典,或者一对多的LookUp<T Key,TElement Values>字典.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public int Id { set ; get ; }
public string Name { set ; get ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
users.Add( new User { Id = 1 , Name = " Scott " });
users.Add( new User { Id = 2 , Name = " Scott " });
users.Add( new User { Id = 3 , Name = " Doe " });
users.Add( new User { Id = 4 , Name = " Doe " });
Dictionary < int , User > query1 = users.ToDictionary(u => u.Id);
ILookup < string , User > query2 = users.ToLookup(u => u.Name);
Console.WriteLine( " ToDictionary示例: " );
foreach (var q in query1)
{
Console.WriteLine( " Key:{0}\tUserName:{1} " , q.Key, q.Value.Name);
}
Console.WriteLine( " ------------------------------------------------- " );
Console.WriteLine( " ToLookup示例: " );
foreach (var q in query2)
{
Console.WriteLine( " Key:{0} " , q.Key);
foreach (var item in q)
{
Console.WriteLine( " \tUserId:{0}\tUserName:{1} " , item.Id, item.Name);
}
}
}
}
}
运行结果:
11 元素操作符(DefaultIfEmpty,ElementAt,ElementAtOrDefault,First,Last,FirstOrDefault,LastOrDefault,Single,SingleOrDefault)
(1)DefaultIfEmpty操作符将一个空集合替换为包含默认值的集合.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public int Id { set ; get ; }
public string Name { set ; get ; }
}
static void Main( string [] args)
{
// 创建测试数据
List < User > users = new List < User > ();
// 如果没有任何用户信息,返回一个默认值
var query = users.DefaultIfEmpty( new User() { Id = 0 , Name = " None " });
foreach (var q in query)
{
Console.WriteLine( " UserId:{0}\tUserName:{1} " , q.Id, q.Name);
}
}
}
}
运行结果:
(2)ElementAt操作符返回集合中给定索引处的元素,如果索引超出范围则会抛出一个index out of range的错误,如果不能确定索引范围,应使用ElementAtOrDefault操作符,ElementAtOrDefault操作符会在索引超出范围时返回一个默认值.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public int Id { set ; get ; }
public string Name { set ; get ; }
}
static void Main( string [] args)
{
// 创建测试数据
string [] names = new string [] { " Scott " , " Dave " , " Steve " , " Joe " };
string name1 = names.ElementAt( 1 );
string name2 = names.ElementAtOrDefault( 8 );
// 返回索引为1的元素
Console.WriteLine(name1);
// 操作范围,返回默认值null,如果为数值类型返回0
Console.WriteLine(name2);
}
}
}
运行结果:
(3)First/Last操作符分别是返回集合中的第一个/最后一个元素,如果不确定是否有第一个或者最后一个值,可以使用FirstOrDefaule/LastOrDefault,它们分别会在First/Last操作符找不到元素的时候返回默认值.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public int Id { set ; get ; }
public string Name { set ; get ; }
}
static void Main( string [] args)
{
// 创建测试数据
string [] names = new string [] { " Scott " , " Dave " , " Steve " , " Joe " };
// 返回索引为0的元素
string name1 = names.First();
// 返回索引为0,并且首字母为T的元素,如果没有则返回默认值null
string name2 = names.FirstOrDefault(u => u.StartsWith( " T " ));
// 返回集合中最后一个元素
string name3 = names.Last();
// 返回集合中最后一个,并且首字母为T的元素,如果没有则返回默认值null
string name4 = names.LastOrDefault(u => u.StartsWith( " T " ));
Console.WriteLine(name1);
Console.WriteLine(name2);
Console.WriteLine(name3);
Console.WriteLine(name4);
}
}
}
运行结果:
(4)Single操作符可以从一个序列中返回唯一满足某个特定条件的元素,如果找不到匹配的元素或者序列返回多个符合条件的元素,都会抛出异常.如果希望找不到元素时返回一个默认值,可以使用SingleOrDefault操作符.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
class User
{
public int Id { set ; get ; }
public string Name { set ; get ; }
}
static void Main( string [] args)
{
// 创建测试数据
string [] names = new string [] { " Scott " , " Dave " , " Steve " , " Joe " };
// 返回集合中以D为首字母的元素
string name1 = names.Single(s => s.StartsWith( " D " ));
// 返回集合中以O为首字母的元素,如果没有则返回默认值null
string name2 = names.SingleOrDefault(s => s.StartsWith( " O " ));
Console.WriteLine(name1);
Console.WriteLine(name2);
}
}
}
运行结果:
12 相等操作符(SequenceEqual)
(1)SequenceEqual操作符可以判定两个集合是否相等,返回值为Boolean值.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < string > names1 = new List < string > { " Scott " , " Dave " , " Steve " , " Joe " };
List < string > names2 = new List < string > { " Scott " , " Dave " , " Steve " , " Joe " };
bool equal1 = names1.SequenceEqual(names2);
names1.Add( " add " );
bool equal2 = names1.SequenceEqual(names2);
Console.WriteLine(equal1);
Console.WriteLine(equal2);
}
}
}
运行结果:
13 量词操作符(All,Any)
(1)All操作符判断集合中所有元素是否满足特定的条件.如果均满足返回True,否则False.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < string > names1 = new List < string > { " Scoet " , " Dave " , " Steve " , " Joe " };
// 是否均包含字母e
bool all1 = names1.All(u => u.Contains( " e " ));
// 是否均以字母e开头
bool all2 = names1.All(u => u.StartsWith( " e " ));
Console.WriteLine(all1);
Console.WriteLine(all2);
}
}
}
运行结果:
(2)Any操作符判断集合中是否至少有一个元素满足特定的条件.有则返回True,否则False.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < string > names1 = new List < string > { " Scoet " , " Dave " , " Steve " , " Joe " };
// 是否至少有一个元素是以D开头的
bool all1 = names1.Any(u => u.StartsWith( " D " ));
// 是否至少有一个元素包含字母i
bool all2 = names1.All(u => u.Contains( " i " ));
Console.WriteLine(all1);
Console.WriteLine(all2);
}
}
}
运行结果:
14 分割操作符(Skip,SkipWhile,Take,TakeWhile)
(1)Skip操作符会跳过指定数量的元素后返回余下的元素,SkipWhile操作符则会通过特定的条件跳过一些元素,然后返回余下的元素.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < int > numbers = new List < int > { 23 , 4 , 55 , 190 , 5 , 54 , 70 };
// 跳过前面3个元素,返回余下的元素
var query1 = numbers.Skip( 3 );
// 跳过前面不满足"大于50"这个条件的,返回余下的元素
var query2 = numbers.SkipWhile(u => u < 50 );
foreach (var q in query1)
{
Console.WriteLine(q);
}
Console.WriteLine( " ---------------------------------------- " );
foreach (var q in query2)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
![2010122921495896.jpg](https://i-blog.csdnimg.cn/blog_migrate/8732aa6731815e2be6ef2b0471593f25.jpeg)
(2)Take操作符会返回集合前面指定数量的元素,TakeWhile操作符则会通过特定的条件选取元素,如果某个元素不符合条件,则从该元素起的元素全部跳过.
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .
// -----------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
// 创建测试数据
List < int > numbers = new List < int > { 23 , 4 , 55 , 190 , 5 , 54 , 70 };
// 获取前面3个元素
var query1 = numbers.Take( 3 );
// 获取满足"小于50"这个条件的元素,只要有哪个不满足,则从该元素起的元素全部忽略
var query2 = numbers.TakeWhile(u => u < 50 );
foreach (var q in query1)
{
Console.WriteLine(q);
}
Console.WriteLine( " ---------------------------------------- " );
foreach (var q in query2)
{
Console.WriteLine(q);
}
}
}
}
运行结果:
小结
标准查询操作符是LINQ查询表达式的构成模块,它们提供了许多查询功能,目前我正在自学这些内容,在此把自己的学习成果分享一下,仅提供给初学者作为参考用,如果有错误的地方请高手指出,我尽快改正~~
相关文章8.Linq初级班 Linq To XML体验(高级编程篇)