前言html
最先使用到Lambda表达式是由于一个需求:
若是一个数组是:int[] s = new int[]{1,3,5,9,14,16,22};
例如只想要这个数组中小于15的元素而后从新组装成一个数组或者直接让s返回一个新数组该怎么截取?数据库
最开始的想法就是将这个s遍历一遍而后判断下再来从新组装成新的数组.好麻烦是否是? 因而便百度到了一个叫作Lambda的东西, 因此用了以后效果以下:编程
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 int[] s = new int []{ 1,3,5,9,14,16,22 }; 6 var result = from n in s where n < 15 select n; 7 int[] b = result.ToArray(); 8 for (int i = 0; i < b.Length; i++) 9 {10 Console.WriteLine(b[i]);11 }12 Console.ReadKey();13 }14 }
打印结果如咱们所想: 1, 3, 5, 9, 14.数组
剩下的就是在真实的项目中接触到的, 在这里只是做为举例, 不作细致讲解: 微信
1 var splitTexts = cmbValidationText.Split(new string[] { IncidentConstant.Comma },
StringSplitOptions.RemoveEmptyEntries); 2 if (cmbValidation.Items != null && cmbValidation.Items.Count > 0) 3 { 4 foreach (var splitText in splitTexts) 5 { 6 bool valid = cmbValidation.Items.Any(item => (item != null) && (item.Enabled) &&
(string.Equals(splitText, item.Prefix, StringComparison.OrdinalIgnoreCase))); 7 8 if (!valid) 9 {10 invalidText += splitText.ToString() + CommaAndBlank;11 isInvalidTextExist = true;12 }13 }14 }15 16 var categoryAndCapabilities = capabilities.Select(item =>17 {18 PRResponseCategory category = null;19 PRCapability prCapability = provisioningManager.GetPRCapabilityByKey(item.PRCapabilityKey.
GetValueOrDefault());20 if (prCapability != null)21 {22 category = statusMonitorDao.GetResponseCategoryByKey(prCapability.ResponseCategoryKey.
GetValueOrDefault());23 }24 return new { Category = category, PRCapability = prCapability, Capability = item };25 })26 .Where(item => (item != null && item.Category != null && item.PRCapability != null))27 .OrderBy(item => item.Category.Code)28 .ThenBy(item => item.PRCapability.AllowNumeric.GetValueOrDefault() ? 1 : 0)29 .ThenBy(item => item.PRCapability.CapabilityCode)30 .GroupBy(item => item.PRCapability.ResponseCategoryKey.GetValueOrDefault())31 .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList());
这里会不会以为很神奇? 那么下面就开始Lambda及Linq之旅吧.ide
1,Linq解析
Linq是Language Integrated Query的缩写, 即"语言集成查询"的意思. 它主要包含4个组件: Linq to Object, Linq to XML, Linq to DataSet 和Linq to Sql.
更多详细内容能够查看一个国外网站: http://www.dotnetperls.com/linq函数
下面步入正题:post
(1),查询表达式学习
查询表达式是一种使用查询语法表示的表达式,它用于查询和转换来自任意支持LINQ的数据源中的数据。查询表达式使用许多常见的C#语言构造,易读简洁,容易掌握。它由一组相似于SQL或XQuery的声明性语法编写的子句组成。每个子句能够包含一个或多个C#表达式。这些C#表达式自己也多是查询表达式或包含查询表达式。网站
查询表达式必须以from子句开头,以select或group子句结束。第一个from子句和最后一个select子句或group子句之间,能够包含一个活多个where子句、let子句、join子 句、orderby子句和group子句,甚至还能够是from子句。它包括8个基本子句,具体说明以下所示。
●from子句:指定查询操做的数据源和范围变量。
●select子句:指定查询结果的类型和表现形式。
●where子句:指定筛选元素的逻辑条件。
●let子句:引入用来临时保存查询表达式中的字表达式结果的范围变量。
●orderby子句:对查询结果进行排序操做,包括升序和降序。
●group子句:对查询结果进行分组。
●into子句:提供一个临时标识符。join子句、group子句或select子句能够经过该标识符引用查询操做中的中坚结果。
●join子句:链接多个用于查询操做的数据源。
1.1,select,from, where子句:
示例1
下面建立一个查询表达式query,该查询表达式查询arr数组中的每个元素。
int[]arr =new int[]{0,1,2,3,4,5,6,7,8,9};
分析1
View Code
示例2
下面建立一个查询表达式query2.该查询表达式查询arr数组中大于6的元素。
View Code
分析2
变量只是保存查询操做,而不是查询的结果。当查询表达式执行查询操做时,才会计算该查询表达式的结果。以上两个变量的类型都属于集合类型。
示例3
下面建立一个查询表达式query。该查询表达式包含两个from子句,他们分别查询两个独立的数据源;arr1数组和arr2数组。最后,使用select子句计算当前元素的和。
View Code
分析3
包含符合from子句的查询表达式
在查询表达式中,有可能查询表达式的数据源中的每个元素自己也做为该查询表达式的数据源。那么要查询数据源中的每个元素中的元素,则须要使用符合from子句。符合from子句相似于嵌套的foreach语句。
1.2,let子句
let子句用来建立一个新的范围变量,它用于存储子表达式的结果。let子句使用编程者提供的表达式的结果初始化该变量。一旦初始化了该范围变量的值,它就不能用于存储其余的值。
示例
下面建立一个查询表达式query。该查询表达式从arr数组中查询为偶数的元素。
View Code
分析
"return n%2==0?true:false"表达式判断n元素是否为偶数。若是是,则返回true,不然返回false。“let isEven =return n%2==0?true:false”表达式使用let子句建立新的范围变量isEven,用来保存"return n%2==0?true:false"表达式的结果。"where isEven"表达式使用where子句筛选isEven的值为true的元素。
1.3,orderby子句
orderby子句可以使返回的查询结果按升序或者降序排序。升序由关键字ascending指定,而降序由关键字descending指定。
注意:orderby子句默认排序方式为升序。
示例
下面建立一个查询表达式query。该查询表达式从arr数组中查询大于1且小于6的元素,而且按照n元素对查询结果进行降序排序。
View Code
分析
orderby子句能够包含一个或多个排序表达式,各个排序表达式使用逗号(,)分隔。
1.4, group子句
group子句用来将查询结果分组,并返回一对象序列。这些对象包含零个或更多个与改组的key值匹配的项,还可使用group子句结束查询表达式。
注意:每个分组都不是单个元素,而是一个序列(也属于集合)。
示例
下面建立一个查询表达式query。该查询表达式从arr数组中查询大于1且小于6的元素,而且按照n%2表达式的值对查询结果进行分组。
View Code
分析
query查询表达式的结果是一个序列(类型为IEnumerable<IGrouping<int,int>>),该序列的元素类型为IGrouping<int,int>.其实,该查询结果中的元素也是一个序列。
1.5, into子句
下面建立一个查询表达式query。该查询表达式从arr数组中查询大于1且小于6的元素,而且按照n%2表达式的值对查询结果进行分组。该查询表达式的具体说明以下所示:
where n>1 && n<6:指定筛选大于1且小于6的元素。
group n by n%2 into g: 按照n%2表达式的值对查询结果进行分组(0和0一组, 1和1 一组),并使用into子句建立临时标识符g。该临时标识符临时保存分组结果。
from sn in g:从g标识符指定的每个分组中查询sn元素。
select sn:表示查询sn元素。
View Code
分析
上述查询表达式的查询结果包括4个元素,依次为二、四、3和5
1.6, join子句
oin子句用来链接两个数据源,即设置两个数据源之间的关系。join子句支持如下3种常见联接方式。
内部联接:元素的连接关系 必须同时知足两个数据源,相似于SQL语句中的inner join子句。
分组联接:包含into子句的join子句。
左外部联接:元素的连接关系必须知足联接中的左数据源,相似于SQL语句中的left join子句。
内部联接:join子句的内部联接要求两个数据源都必须存在相同的值,即两个数据源都必须存在知足联接关系的元素。
示例
下面建立一个查询表达式query。该查询表达式使用join子句联接了arra和arrb数组,具体说明以下。
建立arra数组,它包含10个元素(0~9)。
建立arrb数组,它包含5个元素(0、二、四、6和8)。
建立query查询。
from a in arra:从arra数组中选择元素,并表示为a。
where a < 7: 从arra数组中选择小于7的元素
join b in arrb on a equals b: 将arra和arrb数组进行联接,同时知足a和b相等的条件。其中,b元素是arrb数组中的元素。
select a: 选择a元素。
View Code
分析
上述查询表达式首先选择小于7的元素,(包括0~6),而后再喝arrb数组进行联接,并获取既包含在{0,1,2,3,4,5,6}集合中,又包含在arrb数组中的元素。最终,查询表达式的结果包含4个元素(0、二、4和6)
分组联接:join子句的分组联接包含into子句的join子句的连接。它将左数据源与右数据源的元素一次匹配。左数据源的全部元素都出如今查询结果中。若在右数据源中找到匹配项,则使用匹配的数据,不然用空表示。
(2),使用Linq to XML查询XML文件
在Linq提出以前, 咱们可使用XPath来查询XML文件, 可是用XPath时必须首先知道XML文件的具体结构, 而使用Linq to XML则不须要知道这些.
并且Linq to XML的代码还更加简洁.
View Code
Linq to DataSet其实都和Linq to Object 相似, 这里就不在讲解了.更多内容在如下两个连接:
MSDN之Linq讲解
Linq操做合集
2,Lambda表达式
Lambda表达式能够理解为一个匿名方法, 它能够包含表达式和语句, 而且用于建立委托或转换表达式树.
在使用Lambda表示式时, 都会使用"=>"运算符(读做goes to), 该运算符的左边是匿名方法的输入参数, 右边则是表达式或语句块.
这里主要列举下Linq和Lambda表达式的一些区别:
LINQ的书写格式以下:
from 临时变量 in 集合对象或数据库对象
where 条件表达式
[order by条件]
select 临时变量中被查询的值
[group by 条件]
Lambda表达式的书写格式以下:
(参数列表) => 表达式或者语句块
其中:参数个数:能够有多个参数,一个参数,或者无参数。
参数类型:能够隐式或者显式定义。
表达式或者语句块:这部分就是咱们日常写函数的实现部分(函数体)。
1.查询所有
查询Student表的全部记录。
View Code
2 按条件查询所有:
查询Student表中的全部记录的Sname、Ssex和Class列。
View Code
3.distinct 去掉重复的
查询教师全部的单位即不重复的Depart列。
View Code
4.链接查询 between and
查询Score表中成绩在60到80之间的全部记录。
View Code
5.在范围内筛选 In
View Code
6.or 条件过滤
查询Student表中"95031"班或性别为"女"的同窗记录。
View Code
7.排序
以Class降序查询Student表的全部记录。
View Code
8.count()行数查询
View Code
9.avg()平均
查询'3-105'号课程的平均分。
View Code
10.子查询
查询Score表中的最高分的学生学号和课程号。
View Code
11.分组 过滤
查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
View Code
12.分组
查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
View Code
13. 多表查询
View Code
14,关联多条件查询
感谢@浪子哥 给的建议, 如今加上两张表的关联多条件查询, 只有Linq和Lambda表达式
今天本身又参考园里大神的一些帖子本身写了一个两张表关联查询的Linq及Lambda表达式的Demo, 你们能够看下.
DataTable tableA = tableA.Columns.Add(, ( tableA.Columns.Add(, ( tableA.Columns.Add(, ( DataTable tableB = tableB.Columns.Add(, ( tableB.Columns.Add(, ( tableB.Columns.Add(, ( tableA.Rows.Add(, , tableA.Rows.Add(, , tableA.Rows.Add(, , tableA.Rows.Add(, , tableB.Rows.Add(, , tableB.Rows.Add(, , tableB.Rows.Add(, , tableB.Rows.Add(, , singleQuery = tableA.AsEnumerable().Where(stu => stu.Field<>() > ( item Console.WriteLine(, item.Field<>(), item.Field<>( doubleQuery = a b a.Field<>() == b.Field<>() && a.Field<>() != b.Field<>( a.Field<>(), a.Field<>( Name = a.Field<>( A_Age = a.Field<>( B_Age = b.Field<>( ( item Console.WriteLine( query = a => a.Field<>( b => b.Field<>( (a, b) => a = b = .Where(c => (c.a.Field<>() != c.b.Field<>( .OrderBy(d => d.a.Field<>( .ThenBy(e => e.a.Field<>( .Select(f => Name = f.a.Field<>( A_Age = f.a.Field<>( B_Age = f.b.Field<>( A_Score = f.a.Field<>( B_Score = f.a.Field<>( ( item Console.WriteLine(
73 }74 Console.ReadKey();75 }76 }
解析:
首先能够看出来, Lambda表达式对于这种多表多条件的查询写法的易读性明显没有Linq高, 因此 仍是建议用Linq去写. 运行结果以下图: