LINQ概述


  LINQ,语言集成查询(Language Integrated Query),它允许使用C#或VB代码以查询数据库相同的方式来操作不同的数据源。

LINQ体系结构



从上图可以看出,LINQ总共包括五个部分:LINQ to Objects、LINQ to DataSets、LINQ to SQL、LINQ to Entities、LINQ to XML。

LINQ to Objects:对内存中集合的操作

LINQ to DataSets:对数据集Datatable的操作

LINQ to SQL:对SQL Server数据源的操作,微软把开发的重点从LINQ to SQL转移到了LINQ to Entities并且宣布LINQ to SQL不再提供更新

LINQ to Entities:是 Entity Framework的一部分并且取代LINQ to SQL作为在数据库上使用 LINQ的标准机制

LINQ to XML:对XML数据源的操作

LINQ的语法

  下面是一个简单的示例,查询一个int数组中小于5的元素,并按照从小到大的顺序排列:

		int[] arr = new int[] { 1, 4, 2, 6, 7, 9, 5, 1, 2, 4 };
var query = from r in arr
where r < 5
orderby r
select r;
foreach (var item in query)
{
Console.WriteLine(item);
}
Console.ReadLine();

  由此示例可以看出:LINQ查询表达式以from子句开头,以select子句结束。在两个子句之间,可以使用where、orderby等查询操作符。

  LINQ有两种语法:Lambda语法和Query语法,编译器会在程序编译时转换LINQ查询,以调用相应的扩展方法。

以下是LINQ表达式结构示意图:

引用自百度百科

LINQ to Objects


LINQ to Objects中的扩展方法在System.Core程序集的System.Linq命名空间中定义。

Enumerable类定义的标准查询操作符:



下面介绍使用这些操作符的示例:

首先,我们需要创建基本的实体类Employee:

/// <summary>
/// 员工类
/// </summary>
public class Employee
{
//员工编号
public string EmployeeId { get; private set; }
//员工姓名
public string EmployeeName { get; private set; }
//年龄
public int Age { get; private set; }
//入职日期
public DateTime EntryDate { get; private set; }
//性别
public Sex Sex { get; private set; }
//部门
public string Department { get; private set; }
//薪水
public int Salary { get; private set; }
//爱好
public IEnumerable<string> Hobby { get; private set; } public Employee(string employeeId, string employeeName, int age, DateTime entryDate, Sex sex, Department department, int salary, IEnumerable<string> hobby)
{
this.EmployeeId = employeeId;
this.EmployeeName = employeeName;
this.Age = age;
this.EntryDate = entryDate;
this.Sex = sex;
this.Department = department.ToString();
this.Salary = salary;
this.Hobby = hobby;
}
} //性别
public enum Sex
{
Male,
Female
} //部门
public enum Department
{
HR,
IT,
PD,
FD,
QC,
MD
}

然后,创建列表employees保存10名员工的基本信息:

		 List<Employee> employees = new List<Employee>()
{
new Employee("001","Mike",32,new DateTime(2016,2,20),Sex.Male,Department.IT,200000,new string[] { "swimming","shopping"}),
new Employee("002","Jack",38,new DateTime(2007,5,12),Sex.Male,Department.HR,409989,new string[] { "reading"}),
new Employee("003","Adolph",25,new DateTime(2017,3,23),Sex.Male,Department.IT,100000,new string[] { "play computer games","watch TV","listen to music"}),
new Employee("004","Antony",30,new DateTime(2010,11,20),Sex.Male,Department.FD,320000, new string[] { "play chess","run"}),
new Employee("005","Asa",28,new DateTime(2014,10,10),Sex.Female,Department.FD,120000,new string[] { "shopping"}),
new Employee("006","Bernie",31,new DateTime(2008,4,5),Sex.Male,Department.PD,220000,new string[] { "play basketball"}),
new Employee("007","Carl",26,new DateTime(2015,1,30),Sex.Male,Department.QC,100000,new string[] { "play chess","go fishing"}),
new Employee("008","Duncan",30,new DateTime(2009,6,9),Sex.Male,Department.MD,250000,new string[] { "play computer games"}),
new Employee("009","Aimee",24,new DateTime(2017,1,20),Sex.Female,Department.HR,80000,new string[] { "reading","run"}),
new Employee("010","Cassie",31,new DateTime(2014,3,3),Sex.Female,Department.IT,350000,new string[] { "watch TV" })
};

1)筛选操作符(Where、OfType<TResult>)

Where:根据表达式函数过滤元素

		//查询年龄大于30岁,IT或HR部门所有员工的编号及姓名
var filter = from r in employees
where r.Age > 30 && (r.Department == Department.IT.ToString() || r.Department == Department.HR.ToString())
select r; foreach (var item in filter)
{
Console.WriteLine("EmployId: " +item.EmployeeId + " EmployeeName: " + item.EmployeeName);
} //******************************Output*******************************
//EmployId: 001 EmployeeName: Mike
//EmployId: 002 EmployeeName: Jack
//EmployId: 010 EmployeeName: Cassie
//*******************************************************************

OfType<TResult>:类型筛选

		//筛选出指定数组中所有int类型的元素
object[] data = { "One", 2, 3, "Four", "Five", 6 };
var typeFilter = data.OfType<int>();
foreach (var item in typeFilter)
{
Console.WriteLine(item);
} //******************************Output*******************************
//2
//3
//6
//*******************************************************************

2)投射操作符(Select、SelectMany)

Select:根据选择器函数选择的结果值投射到新的类型元素上

SelectMany:C#编译器把复合的from子句和LINQ查询转换为SelectMany扩展方法,用于迭代序列的序列。

		//查找个人爱好中有reading的员工的姓名
var doubleFrom = from r in employees
from h in r.Hobby
where h == "reading"
select r.EmployeeName;
foreach (var item in doubleFrom)
{
Console.WriteLine(item);
} //******************************Output*******************************
//Jack
//Aimee
//******************************************************************* //--------------------------强势分隔符-------------------------------- //使用SelectMany扩展方法返回个人爱好中有reading的员工的姓名
var selectMany = employees.
SelectMany(r => r.Hobby,
(r, h) => new { Employee = r, Hobby = h }).
Where(r => r.Hobby == "reading").
Select(r => r.Employee.EmployeeName);
foreach (var item in selectMany)
{
Console.WriteLine(item);
}
//******************************Output*******************************
//Jack
//Aimee
//*******************************************************************

3)排序操作符(OrderBy、ThenBy、OrderByDescending、ThenByDescending、Reverse)

OrderBy、OrderByDescending:升序排序、降序排序

ThenBy、ThenByDescending:如果第一次排序有元素相同,进行第二次排序(使用LINQ查询时只需把需要排序的关键字用逗号隔开)

		//按照年龄从大到小排序,如果年龄相同,则按照员工编号正向排序,输出员工的编号、姓名、年龄,
var orderBy = from o in employees
orderby o.Age descending, o.EmployeeId
select o;
foreach (var item in orderBy)
{
Console.WriteLine("EmployeeId: " + item.EmployeeId + " EmployeeName:" + item.EmployeeName + " Age:" + item.Age);
} //******************************Output*******************************
//EmployeeId: 002 EmployeeName: Jack Age:38
//EmployeeId: 001 EmployeeName: Mike Age:32
//EmployeeId: 006 EmployeeName: Bernie Age:31
//EmployeeId: 010 EmployeeName: Cassie Age:31
//EmployeeId: 004 EmployeeName: Antony Age:30
//EmployeeId: 008 EmployeeName: Duncan Age:30
//EmployeeId: 005 EmployeeName: Asa Age:28
//EmployeeId: 007 EmployeeName: Carl Age:26
//EmployeeId: 003 EmployeeName: Adolph Age:25
//EmployeeId: 009 EmployeeName: Aimee Age:24
//*******************************************************************
//--------------------------强势分隔符--------------------------------
//使用ThenBy扩展方法实现年龄相同,按员工编号正向排序
var thenBy = employees
.OrderByDescending(t => t.Age)
.ThenBy(t => t.EmployeeId)
.Select(t => "EmployeeId: " + t.EmployeeId + " EmployeeName:" + t.EmployeeName + " Age:" + t.Age);
foreach (var item in thenBy)
{
Console.WriteLine(item);
} //******************************Output*******************************
//EmployeeId: 002 EmployeeName: Jack Age:38
//EmployeeId: 001 EmployeeName: Mike Age:32
//EmployeeId: 006 EmployeeName: Bernie Age:31
//EmployeeId: 010 EmployeeName: Cassie Age:31
//EmployeeId: 004 EmployeeName: Antony Age:30
//EmployeeId: 008 EmployeeName: Duncan Age:30
//EmployeeId: 005 EmployeeName: Asa Age:28
//EmployeeId: 007 EmployeeName: Carl Age:26
//EmployeeId: 003 EmployeeName: Adolph Age:25
//EmployeeId: 009 EmployeeName: Aimee Age:24
//*******************************************************************

Revise:使用扩展方法反转集合中的元素顺序

		//按照年龄从大到小排序后再反转元素的顺序
var reverse = employees
.OrderByDescending(r => r.Age)
.Reverse()
.Select(r => "EmployeeId: " + r.EmployeeId + " EmployeeName:" + r.EmployeeName + " Age:" + r.Age);
foreach (var item in reverse)
{
Console.WriteLine(item);
} //******************************Output*******************************
//EmployeeId: 009 EmployeeName: Aimee Age:24
//EmployeeId: 003 EmployeeName: Adolph Age:25
//EmployeeId: 007 EmployeeName: Carl Age:26
//EmployeeId: 005 EmployeeName: Asa Age:28
//EmployeeId: 008 EmployeeName: Duncan Age:30
//EmployeeId: 004 EmployeeName: Antony Age:30
//EmployeeId: 010 EmployeeName: Cassie Age:31
//EmployeeId: 006 EmployeeName: Bernie Age:31
//EmployeeId: 001 EmployeeName: Mike Age:32
//EmployeeId: 002 EmployeeName: Jack Age:38
//*******************************************************************

4)连接操作符(Join、GroupJoin)

为了完成这部分的示例,我们需要准备新的实体类和列表

/// <summary>
/// 部门信息
/// </summary>
public class DepartmentInfo
{
//部门编号
public string DepartmentId { get; private set; }
//部门名称
public string DepartmentName { get; private set; }
//部门总监
public string Director { get; private set; } public DepartmentInfo(string departmentId, string departmentName, string director)
{
this.DepartmentId = departmentId;
this.DepartmentName = departmentName;
this.Director = director;
}
} /// <summary>
/// 杰出团队
/// </summary>
public class OutstandingTeam
{
public int Year { get; private set; }
public string Department { get; private set; } public OutstandingTeam(int year, string department)
{
this.Year = year;
this.Department = department;
}
}

创建列表departmentInfo保存各部门的信息

		List<DepartmentInfo> deparmentInfo = new List<DepartmentInfo>()
{
new DepartmentInfo("001","HR","Oliver"),
new DepartmentInfo("002","IT","Oscar"),
new DepartmentInfo("003","PD","ELLA"),
new DepartmentInfo("004","FD","Alice"),
new DepartmentInfo("005","QC","Kai")
};

创建列表outstandingTeams保存2010年起获得杰出团队的部门

 		List<OutstandingTeam> outstandingTeams = new List<OutstandingTeam>()
{
new OutstandingTeam(2010,"IT"),
new OutstandingTeam(2011,"FD"),
new OutstandingTeam(2012,"HR"),
new OutstandingTeam(2013,"IT"),
new OutstandingTeam(2014,"QC"),
new OutstandingTeam(2015,"HR"),
new OutstandingTeam(2016,"HR"),
new OutstandingTeam(2017,"MD")
};

Join:根据特定的条件合并两个数据源

		//查询员工的姓名,部门以及该部门的总监
var join = from j in employees
join d in deparmentInfo
on j.Department equals d.DepartmentName
select new
{
j.EmployeeName,
j.Department,
d.Director
};
foreach (var item in join)
{
Console.WriteLine("EmployeeName: " + item.EmployeeName + " Department:" + item.Department + " Director:" + item.Director);
} //******************************Output*******************************
//EmployeeName: Mike Department:IT Director:Oscar
//EmployeeName: Jack Department:HR Director:Oliver
//EmployeeName: Adolph Department:IT Director:Oscar
//EmployeeName: Antony Department:FD Director:Alice
//EmployeeName: Asa Department:FD Director:Alice
//EmployeeName: Bernie Department:PD Director:ELLA
//EmployeeName: Carl Department:QC Director:Kai
//EmployeeName: Aimee Department:HR Director:Oliver
//EmployeeName: Cassie Department:IT Director:Oscar
//*******************************************************************

这时候我们会发现,输出的内容里面少了员工Duncan的信息,检查后发现,原来deparmentInfo没有添加MD部门的相关信息,此时希望查询所有员工,若匹配不到该部门信息,Director返回N/A。

		//查询员工的姓名,部门以及该部门的总监,若匹配不到该部门信息,Director返回N/A
var leftjoin = from j in employees
join d in deparmentInfo
on j.Department equals d.DepartmentName into jd
from d in jd.DefaultIfEmpty()
select new
{
j.EmployeeName,
j.Department,
Director = d == null ? "N/A" : d.Director
};
foreach (var item in leftjoin)
{
Console.WriteLine("EmployeeName: " + item.EmployeeName + " Department:" + item.Department + " Director:" + item.Director);
} //******************************Output*******************************
//EmployeeName: Mike Department:IT Director:Oscar
//EmployeeName: Jack Department:HR Director:Oliver
//EmployeeName: Adolph Department:IT Director:Oscar
//EmployeeName: Antony Department:FD Director:Alice
//EmployeeName: Asa Department:FD Director:Alice
//EmployeeName: Bernie Department:PD Director:ELLA
//EmployeeName: Carl Department:QC Director:Kai
//EmployeeName: Duncan Department:MD Director:N/A
//EmployeeName: Aimee Department:HR Director:Oliver
//EmployeeName: Cassie Department:IT Director:Oscar
//*******************************************************************

GroupJoin:基于键相等对两个序列的元素进行关联并对结果进行分组。

		//查找每个部门获得杰出团队的年份
var groupJoin = from d in deparmentInfo
join o in outstandingTeams on d.DepartmentName equals o.Department into g
select new
{
DepartmentName = d.DepartmentName,
Years = g
};
foreach (var item in groupJoin)
{
Console.WriteLine("Department:" + item.DepartmentName); if (item.Years.Count() == 0)
{
Console.WriteLine("Never won the award");
}
foreach (var champions in item.Years)
{
Console.WriteLine(champions.Year);
} } //******************************Output*******************************
//Department: HR
//2012
//2015
//2016
//Department: IT
//2010
//2013
//Department: PD
// Never won the award
// Department:FD
//2011
//Department: QC
//2014
//*******************************************************************

5)组合操作符(GroupBy、ToLookup)

GroupBy:根据关键字值对查询结果进行分组。

		//查询每个部门及人数
var groupBy = from e in employees
group e by e.Department into g
select new
{
g.Key,
Count = g.Count()
};
foreach (var item in groupBy)
{
Console.WriteLine("Department: " + item.Key + " Count: " + item.Count);
}
//******************************Output*******************************
//Department: IT Count: 3
//Department: HR Count: 2
//Department: FD Count: 2
//Department: PD Count: 1
//Department: QC Count: 1
//Department: MD Count: 1
//*******************************************************************

ToLookup:通过创建一对多的字典来组合元素

		//使用ToLookup实现爱好阅读的员工姓名
var toLookup = (from e in employees
from h in e.Hobby
select new
{
Hobby = h,
Name = e.EmployeeName
}).ToLookup(he => he.Hobby, he => he.Name); if (toLookup.Contains("reading"))
{
foreach (var item in toLookup["reading"])
{
Console.WriteLine(item);
}
} //******************************Output*******************************
//Jack
//Aimee
//*******************************************************************

6)限定操作符(Any、All、Contains)

Any:是否包含满足条件的元素

		//是否有小于20岁的员工
bool any = employees.Any(r => r.Age < 20);
Console.WriteLine(any); //******************************Output*******************************
//False
//*******************************************************************

ALL:是否所有元素都满足条件

		//是否所有员工都大于20岁
bool all = employees.All(r => r.Age > 20);
Console.WriteLine(all); //******************************Output*******************************
//True
//*******************************************************************

Contains:检索某个元素是否在集合中

        //员工列表中是否包含david
Employee david = new Employee("011", "David", 28, new DateTime(2017, 5, 21), Sex.Male, Department.IT, 100000, new string[] { "run" });
employees.Add(david);
bool contains = employees.Contains(david);
Console.WriteLine(contains); //******************************Output*******************************
//True
//*******************************************************************

7)分区操作符(Take、Skip、TakeWhile、SkipWhile)

Take:从集合中提取指定数量的元素

Skip:跳过集合中指定数量的元素

 		//忽略薪水最高的5位,查询剩余部分薪水最高的员工姓名及薪水
var skip = (from e in employees
orderby e.Salary descending
select e).Skip(5).Take(1);
foreach (var item in skip)
{
Console.WriteLine("EmployeeName: " + item.EmployeeName + " Salary: " + item.Salary);
} //******************************Output*******************************
//EmployeeName: Mike Salary: 200000
//*******************************************************************

TakeWhile:提取条件为真时的元素

		//取集合中满足条件salary大于1000000之前的所有员工的姓名和薪水
var takeWhile = (from e in employees
select e).TakeWhile(r => r.Salary > 100000);
foreach (var item in takeWhile)
{
Console.WriteLine("EmployeeName: " + item.EmployeeName + " Salary: " + item.Salary);
} //******************************Output*******************************
//EmployeeName: Mike Salary: 200000
//EmployeeName: Jack Salary: 409989
//*******************************************************************

SkipWhere:跳过集合中满足条件的元素,当条件不成立时返回剩余的所有元素

		//跳过集合中满足条件salary大于100000的元素,当条件不成立时返回剩余的所有元素
var skipWhile = (from e in employees
select e).SkipWhile(r => r.Salary > 100000);
foreach (var item in skipWhile)
{
Console.WriteLine("EmployeeName: " + item.EmployeeName + " Salary: " + item.Salary);
} //******************************Output*******************************
//EmployeeName: Adolph Salary: 100000
//EmployeeName: Antony Salary: 320000
//EmployeeName: Asa Salary: 120000
//EmployeeName: Bernie Salary: 220000
//EmployeeName: Carl Salary: 100000
//EmployeeName: Duncan Salary: 250000
//EmployeeName: Aimee Salary: 80000
//EmployeeName: Cassie Salary: 350000
//*******************************************************************

8)Set操作符(Distinct、Union、Intersect、Except、Zip)

Distinct:从集合中删掉重复的元素

		//给所有员工的薪水排序,去掉重复的
var distinct = (from e in employees
orderby e.Salary
select e.Salary).Distinct(); foreach (var item in distinct)
{
Console.WriteLine(item);
} //******************************Output*******************************
//80000
//100000
//120000
//200000
//220000
//250000
//320000
//350000
//409989
//*******************************************************************

Union、Intersect、Except:并集、交集、差集

首先,我们准备两个集合:员工姓名以A开头和员工姓名以E结尾

		var startWithA = (from e in employees
where e.EmployeeName.StartsWith("A")
select e).ToList(); var endWithE = (from e in employees
where e.EmployeeName.ToUpper().EndsWith("E")
select e).ToList();

以下分别取两个集合的并集、交集、差集:

		//查询两个集合的并集
var union = startWithA.Union(endWithE);
foreach (var item in union)
{
Console.WriteLine(item.EmployeeName);
} //******************************Output*******************************
//Adolph
//Antony
//Asa
//Aimee
//Mike
//Bernie
//Cassie
//******************************************************************* //--------------------------强势分隔符-------------------------------- //查询两个集合的交集
var intersect = startWithA.Intersect(endWithE);
foreach (var item in intersect)
{
Console.WriteLine(item.EmployeeName);
} //******************************Output*******************************
//Aimee
//******************************************************************* //--------------------------强势分隔符-------------------------------- //查询两个集合的差集
var except = startWithA.Except(endWithE);
foreach (var item in except)
{
Console.WriteLine(item.EmployeeName);
} //******************************Output*******************************
//Adolph
//Antony
//Asa
//*******************************************************************

Zip:把两个集合中对应的项目合并起来,在到大较小集合的末尾时停止

		//把两个集合中对应的项的姓名合并起来
var zip = startWithA.Zip(endWithE, (first, second) => first.EmployeeName + "+" + second.EmployeeName);
foreach (var item in zip)
{
Console.WriteLine(item);
} //******************************Output*******************************
//Adolph+Mike
//Antony+Bernie
//Asa+Aimee
//Aimee+Cassie
//*******************************************************************

9)元素操作符(First、FirstOrDefault、Last、LastOrDefault、ElementAt、ElementAtOrDefault、Single、SingleOrDefault)

First:返回第一个满足条件的元素;若不存在,则引发异常。

FirstOrDefault:返回第一个满足条件的元素;若不存在,则返回默认值。

 		//查询年龄大于30岁的第一位员工的姓名
var first = (from e in employees
orderby e.Age
select e).First(r => r.Age > 30);
Console.WriteLine(first.EmployeeName); //******************************Output*******************************
//Bernie
//*******************************************************************

假设需查询年龄大于50岁的第一位员工的姓名,我们将上述代码中年龄修改为50

		var first = (from e in employees
orderby e.Age
select e).First(r => r.Age > 50);
Console.WriteLine(first.EmployeeName);

执行后发现异常



此时使用FirstOrDefault操作符:

		//查询年龄大于50岁的第一位员工的姓名,若不存在,则返回N/A
var firstOrDefault = (from e in employees
orderby e.Age
select e).FirstOrDefault(r => r.Age > 50);
Console.WriteLine(firstOrDefault == null ? "N/A" : firstOrDefault.EmployeeName); //******************************Output*******************************
//N/A
//*******************************************************************

Last:返回最后一个满足条件的元素;若不存在,则引发异常。

LastOrDefault:返回最后一个满足条件的元素;若不存在,则返回默认值。

ElementAt:返回指定索引位置的元素;若不存在,则引发异常。

ElementAtOrDefault:返回指定索引位置的元素;若不存在,则返回默认值。

Single:只返回一个满足条件的元素;若不存在或多个元素都满足条件,则引发异常。

SingleOrDefault:只返回一个满足条件的元素;若不存在或多个元素都满足条件,则返回默认值。

10)聚合操作符(Count、Sum、Min、Max、Average、Aggregate)

Count:返回集合中的项数

		//查找有一个以上爱好的员工的姓名、爱好的数量及部门
var count = from e in employees
let numberHobby = e.Hobby.Count()
where numberHobby > 1
select new
{
e.EmployeeName,
numberHobby,
e.Department
};
foreach (var item in count)
{
Console.WriteLine("EmployeeName: " + item.EmployeeName + " NumberHobby: " + item.numberHobby + " Department: " + item.Department);
} //******************************Output*******************************
//EmployeeName: Mike NumberHobby: 2 Department: IT
//EmployeeName: Adolph NumberHobby: 3 Department: IT
//EmployeeName: Antony NumberHobby: 2 Department: FD
//EmployeeName: Carl NumberHobby: 2 Department: QC
//EmployeeName: Aimee NumberHobby: 2 Department: HR
//*******************************************************************

Sum:计算所有值的总和

Min、Max、Average:最小值、最大值、平均值

		//计算所有员工薪水的总和
var sum = (from e in employees
select e.Salary).Sum/*Min、Max、Average*/();
Console.WriteLine(sum.ToString("N0")); //******************************Output*******************************
//2,149,989
//*******************************************************************

Aggregate:对序列进行累加

		//初始值为50000000,依次累加所有员工的薪水
var aggregate = (from e in employees
select e.Salary).Aggregate(5000000, (x, y) => x + y, r => r * 2);
Console.WriteLine(aggregate.ToString("N0")); //******************************Output*******************************
//14,299,978
//*******************************************************************

说明:Aggregate扩展方法的第一个参数为初始值。第二个参数是一个表达式,用来对每个元素进行计算(第一个参数是累加变量,第二个参数是当前值)。第三个参数是一个表达式,用来对最终结果进行计算。

11)转换操作符(ToArray、AsEnumerable、ToList、ToDictionary、Cast<TResult>)

使用转换操作符会立即执行查询,将查询结果放在数组、列表、字典中。

		//将年龄大于30岁的元素放入list中再循环输出。
List<Employee> employeeList = (from e in employees
where e.Age > 30
select e).ToList();
foreach (var item in employeeList)
{
Console.WriteLine("EmployeeName: " + item.EmployeeName + " Age:" + item.Age);
} //******************************Output*******************************
//EmployeeName: Mike Age:32
//EmployeeName: Jack Age:38
//EmployeeName: Bernie Age:31
//EmployeeName: Cassie Age:31
//*******************************************************************

12)生成操作符(Empty、Range、Repeat)

生成操作符不是扩展方法,而是返回序列的静态方法。在LINQ to Objects中,这些方法可用于Enumerable类。

Empty:生成空集合

		//生成一个int类型的空序列
var empty = Enumerable.Empty<int>();
Console.WriteLine(empty.Count()); //******************************Output*******************************
//0
//*******************************************************************

Range:生成一系列数字的集合

		//生成一个从1开始,10个元素的序列
var range = Enumerable.Range(1, 10);
foreach (var item in range)
{
Console.WriteLine(item);
} //******************************Output*******************************
//1
//2
//3
//4
//5
//6
//7
//8
//9
//10
//*******************************************************************

Repeat:返回始终重复一个值的集合

		//生成一个10个元素,每个元素都是5的序列
var repeat = Enumerable.Repeat(5, 10);
foreach (var item in repeat)
{
Console.WriteLine(item);
} //******************************Output*******************************
//5
//5
//5
//5
//5
//5
//5
//5
//5
//5
//*******************************************************************

本篇就此结束,主要介绍了LINQ的体系结构、基本语法以及LINQ to Obejcts中标准查询操作符的使用方法。

示例代码下载:https://github.com/Answer-Geng/LINQ

LINQ之LINQ to Objects(上)的更多相关文章

  1. C# ~ 从 XML 到 Linq 到 Linq to XML

    .XML 可扩展标记语言 (Extensible Markup Language), 标记 (markup) 是关键部分,是标准通用标记语言 (Standard Generalized Markup ...

  2. Linq之Linq to XML

    目录 写在前面 系列文章 linq to xml 总结 写在前面 在很多情况下,都可以见到使用xml的影子.例如,在 Web 上,在配置文件.Microsoft Office Word 文件(将wor ...

  3. Linq之Linq to Sql

    目录 写在前面 系列文章 Linq to sql 总结 写在前面 上篇文章介绍了linq to xml的相关内容,linq to xml提供一种更便捷的创建xml树,及查询的途径.这篇文章将继续介绍l ...

  4. C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)

    学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...

  5. Linq技术四:动态Linq技术 -- Linq.Expressions

    前面介绍了Linq的三个方面应用:Linq to SQL, Linq to XML和Linq to Object,这篇介绍一下动态Linq的实现方式及应用场景. 命名空间: System.Linq; ...

  6. Linq之Linq to Objects

    目录 写在前面 系列文章 linq to objects 总结 写在前面 上篇文章介绍了linq的延迟加载特性的相关内容,从这篇文章开始将陆续介绍linq to Objects,linq to xml ...

  7. LINQ(LINQ to Entities)

    LINQ to Entities 是 LINQ 中最吸引人的部分.它让你可以使用标准的 C# 对象与数据库的结构和数据打交道.使用 LINQ to Entities 时,LINQ 查询在后台转换为 S ...

  8. LINQ(LINQ to DataSet)

    http://www.cnblogs.com/SkySoot/archive/2012/08/21/2649471.html DataTable.Select()方法使用和 SQL 相似的过滤语法从 ...

  9. LINQ以及LINQ to Object 和LINQ to Entities

    LINQ的全称是Language Integrated Query,中文译成“语言集成查询”,是一种查询技术. LINQ查询通过提供一种跨各种数据源和数据格式使用数据的一致模型,简化了查询过程.LIN ...

随机推荐

  1. AVL树的旋转操作详解

    [0]README 0.0) 本文部分idea 转自:http://blog.csdn.net/collonn/article/details/20128205 0.1) 本文仅针对性地分析AVL树的 ...

  2. 云计算之路-阿里云上:数据库连接数过万的真相,从阿里云RDS到微软.NET Core

    在昨天的博文中,我们坚持认为数据库连接数过万是阿里云RDS的问题,但后来阿里云提供了当时的数据库连接情况,让我们动摇了自己的想法. 帐户 连接数 A 4077 B 3995 C 741 D 698 E ...

  3. MCDownloader(iOS下载器)说明书

    示例 前言 很多iOS应用中都需要下载数据,并对这些下载的过程和结果进行管理,因此我才有了写这个MCDownloader的想法.在IOS 文件下载器-MCDownloadManager这篇文章中,我使 ...

  4. Spring+SpringMVC+MyBatis+easyUI整合优化篇(六)easyUI与富文本编辑器UEditor整合

    日常啰嗦 本来这一篇和接下来的几篇是打算讲一下JDBC和数据库优化的,但是最近很多朋友加我好友也讨论了一些问题,我发现大家似乎都是拿这个项目作为练手项目,作为脚手架来用的,因此呢,改变了一下思路,JD ...

  5. 关于php 高并发解决的一点思路

    涉及抢购.秒杀.抽奖.抢票等活动时,为了避免超卖,那么库存数量是有限的,但是如果同时下单人数超过了库存数量,就会导致商品超卖问题.那么我们怎么来解决这个问题呢,我的思路如下(伪代码): sql1:查询 ...

  6. 类似智能购票的demo--进入页面后默认焦点在第一个输入框,输入内容、回车、right时焦点自动跳到下一个,当跳到select时,下拉选项自动弹出,并且可以按上下键选择,选择完成后再跳到下一个。

    要实现的效果:进入页面后默认焦点在第一个输入框,输入内容.回车.right时焦点自动跳到下一个,当跳到select时,下拉选项自动弹出,并且可以按上下键选择,选择完成后再跳到下一个. PS:自己模拟的 ...

  7. android参数传递的几种方法

    Intent Intent i=new Intent(当前Activity.this,目标Activity.class); 1.传单值 传入: i. i.putExtra("名称" ...

  8. 交作业啊,python爬取58的页面

    第一次写博文,好紧张啊,写这么烂怎么给别人看啊先做下总结: 刚开始学习python,自我感觉python写起来确实很方便,各种库,各种语法糖,不过刚接触,一下子记不下来这么多东西,总感觉乱乱的,用的多 ...

  9. 一款Modbus设备调试工具Winform(包括SRC0001、海康威视、TTS以及各种类型LED的测试)

    1.SRC寄存器读写测试 2.采集数据终端模块(这里是康海时代)调试 3.RS485传感器设备调试 4.LED/TTS/海康威视等展示设备调试 5.Modbus等协议规约资料及4-20mA设备调试 以 ...

  10. PhpMyAdmin导入数据库大小限制?

    问题描述: 在phpMyAdmin中导入数据库时,出现问题: 1. 如果按照扩展名.sql导入,提示如下: 没有接收到要导入的数据.可能是文件名没有提交,也可能是文件大小超出 PHP 限制. 2. 如 ...