LINQ查询表达式的基本语法很容易掌握,它使用C#常见的语言构造,从外观上看,和我们常用的SQL类似,并且查询表达式中的变量可以用匿名类型,所以在很多情况下,不需要指定变量类型就可以构建LINQ表达式。
LINQ的数据源可以是数据库对象或是XML流等,也可以使实现了IEnumerable或者泛型IEnumberable<T>接口的集合对象。
LINQ的基本语法包含如下的8个上下文关键字,这些关键字和具体的说明如下:
关键字 | 说明 |
from | 指定范围变量和数据源 |
where | 根据bool表达式从数据源中筛选数据 |
select | 指定查询结果中的元素所具有的类型或表现形式 |
group | 对查询结果按照键值进行分组(IGrouping<TKey,TElement>) |
into | 提供一个标识符,它可以充当对join、group或select子句结果的引用 |
orderby | 对查询出的元素进行排序(ascending/descending) |
join | 按照两个指定匹配条件来Equals连接两个数据源 |
let | 产生一个用于存储查询表达式中的子表达式查询结果的范围变量 |
1.from子句
如果要写一个LINQ表达式,就必须是以from子句开头。个人觉得from子句中需要注意的地方就是多个from子句的书写。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace LINQ { /// <summary> /// LINQ,重点是感悟from子句中的查询变量的灵活 /// </summary> class Program { static void Main(string[] args) { //1单个form子句 string[] values = { "LINQ学习","LINQ基本语句","from子句","单个from子句"}; var value = from v in values where v.IndexOf("LINQ") > -1 select new { v, v.Length }; foreach (var n in value) { Console.WriteLine("{0},{1}",n.v,n.Length ); } Console.ReadKey(false); //2使用LINQ查询ArrayList ArrayList gList = new ArrayList(); gList.Add(new GustInfo { Name="DebugLZQ", Age=26, Tel="88888888"}); gList.Add(new GustInfo { Name="博客园",Age=6, Tel ="666666"}); gList.Add(new GustInfo { Name = "M&MSoft", Age =9, Tel = "55555" }); var query = from GustInfo gust in gList where gust.Age > 9 select gust;//范围变量gust制定了数据类型 foreach (GustInfo g in query) { Console.WriteLine("{0} 年龄:{1} 电话:{2}",g.Name,g.Age,g.Tel ); } Console.ReadKey(false); //3复合from子句 List<GustInfo2> gList2 = new List<GustInfo2>() { new GustInfo2{ Name="DebugLZQ",Age=26,TelTable=new List<string>(){"8888888","138******"}}, new GustInfo2{ Name="博客园",Age=6,TelTable =new List<string>(){"666666","138******"}}, new GustInfo2{ Name="M&MSoft",Age=9,TelTable=new List<string>(){"55555","138******"}} }; //gust、tel都是查询变量,作用域为当前查询语句!!! var query2 = from gust in gList2 from tel in gust.TelTable where tel.IndexOf("5555") > -1 select gust; foreach (var g in query2) { Console.WriteLine("{0} 年龄{1}",g.Name,g.Age ); foreach (var t in g.TelTable) { Console.WriteLine("电话:{0}",t); } } Console.ReadKey(false); //4多个from子句 var query3 = from GustInfo gust in gList where gust.Age > 6 from GustInfo2 gust2 in gList2 where gust2.Age> 9 select new { gust, gust2 };//查询结果定制 foreach (var g in query3) { Console.WriteLine("{0} {1}", g.gust.Name, g.gust2.Name); } Console.ReadKey(false); } } }
程序的运行结果如下:
程序中列举了from子句的用法示例,注意复合from子句和多个from子句的书写,同时需要理解范围变量和数据源变量这两个概念
2.where子句
where子句,它是LINQ表达式的元素筛选机制,除了开始和结束的位置,它几乎可以出现在LINQ表达式的任意位置上。
在一个LINQ表达式中,可以有where子句,也可以没有;可以有一个,也可以有多个;多个where子句之间的逻辑关系相当于逻辑“与”,每个where子句可以包含1个或多个bool逻辑表达式,这些条件成为谓词,谓词逻辑之间用的是“&&”“||”等而不是SQL中的and 、or。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ_WHERE { /// <summary> /// LINQ where子句 /// </summary> class Program { static void Main(string[] args) { //1常见的where语句 List<GustInfo> gList = new List<GustInfo>() { new GustInfo(){ Name="DebugLZQ", Age=26,Tel="88888888"}, new GustInfo(){ Name="cnblogs",Age=6,Tel="666666"}, new GustInfo(){ Name="M&MSoft",Age=9,Tel="55555"} }; var query = from gust in gList where (gust.Name.Length > 7 || gust.Name.Substring(0, 1) == "M") && gust.Age > 9 select new { gust.Name, gust.Age }; foreach (var g in query) { Console.WriteLine("{0},{1}", g.Name, g.Age); } Console.ReadKey(false); //2.在where子句中使用自定义函数 var query2 = from GustInfo gust in gList where gust.Name.Length > 5 && Check(gust.Name) select gust; foreach (var g in query2) { Console.WriteLine("{0},{1},{2}", g.Name, g.Age, g.Tel); } Console.ReadKey(false); //3.动态谓词的筛选 //定义动态谓词数组,在实际开发中可以动态获得 string[] names = { "SB","XXX","***","@@@","一些敏感词"}; var query3 = from GustInfo guest in gList where !names.Contains(guest.Name) select guest; foreach (var q in query3) { Console.WriteLine("{0} 年龄:{1},电话:{2}",q.Name,q.Age,q.Tel ); } Console.ReadKey(false); } //自定义函数 static bool Check(string name) { if (name.Substring(0, 1) == "N") return false; return true; } } }
需要注意一些常用的where子句的写法。程序的运行结果如下:
3.Select子句
在select子句上可以非常灵活的处理查询到的元素,然后再把结果返回。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ_select { /// <summary> /// LINQ select /// 在select子句上,可以非常灵活的处理查询到的元素,然后再把结果返回 /// </summary> class MyGustInfo { public string Name { get; set; } public int Age { get; set; } } class Program { static void Main(string[] args) { List<GustInfo> gList = new List<GustInfo>() { new GustInfo(){ Name="DebugLZQ", Age=25, Tel="88888888"}, new GustInfo(){ Name="cnblogs", Age=6, Tel="666666"}, new GustInfo(){ Name="M&M", Age=9, Tel="55555"} }; var query = from gust in gList where gust.Age >= 9 && gust.Age <= 30 select gust.Name.Replace("&", "mm");//select子句灵活应用 var query2 = from gust in gList where gust.Age >= 9 && gust.Age <= 30 select MyProc(gust.Name); var query3 = from gust in gList where gust.Age >= 9 && gust.Age <= 30 select new { gust.Name,gust.Age}; var query4 = from gust in gList where gust.Age >= 9 && gust.Age <= 30 select new MyGustInfo { Name=gust.Name+"My", Age=gust.Age+1};//对查询结果进行投影 foreach (var v in query) { Console.WriteLine(v); } foreach (var v in query2) { Console.WriteLine(v); } foreach (var v in query3) { Console.WriteLine(v.Name+v.Age ); } foreach (var v in query4) { Console.WriteLine(v.Name+v.Age ); } Console.ReadKey(false); } static string MyProc(string s) { return s + "Better"; } } }
程序的运行结果如下:
4.group子句
根据语法的规定,LINQ表达式必须以from子句开头,以select或group子句结束,所以除了使用select来返回结果外,也可以使用group子句来返回元素分组后的结果。
group子句返回的是一个基于IGrouping<TKey,TElement>泛型接口的对象序列。
语法和SQL的group有点区别,不注意的话可能会写错。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ_group { /// <summary> /// LINQ group子句 /// </summary> class Program { static void Main(string[] args) { List<GustInfo> gList = new List<GustInfo>() { new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"}, new GustInfo(){ Name="Sarah",Age=25,Tel="159********"}, new GustInfo(){ Name="Jerry",Age=35,Tel="135********"}, new GustInfo(){ Name="M&M",Age=16,Tel="136********"}, new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"}, new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"}, }; var query = from guest in gList group guest by guest.Name.Substring(0, 1);//分组键key是string类型 //遍历键值和键值所属元素 foreach (IGrouping<string, GustInfo> guestGroup in query) { Console.WriteLine("分组键:{0}",guestGroup.Key ); foreach (var g in guestGroup) { Console.WriteLine("{0} 年龄:{1} 电话:{2}",g.Name,g.Age,g.Tel ); } } Console.ReadKey(false); Console.WriteLine("-----------------------------------"); var query2 = from guest in gList group guest by guest.Age > 20;//分组键key是bool类型表达式的结果 foreach (IGrouping<bool, GustInfo> guestGroup in query2) { Console.WriteLine("年龄是否大于20 分组键:{0}", guestGroup.Key); foreach (var g in guestGroup) { Console.WriteLine("{0} 年龄:{1} 电话:{2}", g.Name, g.Age, g.Tel); } } Console.ReadKey(false); } } }
程序的运行结果如下:
5.into子句
into子句作为一个临时标识符,用于group、select、join子句中充当其结果的引用。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ_into { /// <summary> /// LINQ group /// </summary> class Program { static void Main(string[] args) { List<GustInfo> gList = new List<GustInfo>() { new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"}, new GustInfo(){ Name="Sarah",Age=25,Tel="159********"}, new GustInfo(){ Name="Jerry",Age=35,Tel="135********"}, new GustInfo(){ Name="M&M",Age=16,Tel="136********"}, new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"}, new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"}, }; //1.into用于group子句 var query = from guest in gList group guest by guest.Name.Substring(0, 1) into grguest orderby grguest.Key descending select grguest; var query2 = from guest in gList group guest by guest.Name.Substring(0, 1) into grguest orderby grguest.Key ascending select grguest; //2.select 子句中的into子句 var query3 = from guest in gList select new { NewName = guest.Name, NewAge = guest.Age } into newguest orderby newguest.NewAge select newguest; foreach (var guestGroup in query) { Console.WriteLine("分组键:{0}",guestGroup.Key ); foreach (var g in guestGroup) { Console.WriteLine("{0} 电话:{1}",g.Name,g.Tel ); } } Console.ReadKey(false); foreach (var newg in query3) { Console.WriteLine("{0} 年龄:{1}",newg.NewName,newg.NewAge ); } Console.ReadKey(false); } } }
程序运行结果如下:
6.orderby子句、thenby子句
LINQ可以按照元素的一个或多个属性对元素进行排序。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ_orderby { class Program { /// <summary> /// LINQ orderby (ascending descending) /// </summary> /// <param name="args"></param> static void Main(string[] args) { List<GustInfo> gList = new List<GustInfo>() { new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"}, new GustInfo(){ Name="Sarah",Age=25,Tel="159********"}, new GustInfo(){ Name="Jerry",Age=35,Tel="135********"}, new GustInfo(){ Name="M&M",Age=16,Tel="136********"}, new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"}, new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"}, }; //按照年龄排序 var query = from guest in gList orderby guest.Age select guest; var query1 = from guest in gList orderby guest.Age ascending select guest; var query2 = from guest in gList orderby guest.Age descending select guest; //按照年龄进行排序,按照名字字数进行次要排序 var query3 = from guest in gList orderby guest.Age, guest.Name.Length select guest; var query4 = from guest in gList orderby guest.Age descending , guest.Name.Length ascending select guest; var query5 = from guest in gList orderby guest.Age, guest.Name.Length,guest.Tel select guest; foreach (var guest in query2) { Console.WriteLine("{0} 年龄:{1} 电话:{2}",guest.Name,guest.Age,guest.Tel ); } Console.ReadKey(false); foreach (var guest in query4) { Console.WriteLine("{0} 年龄:{1} 电话:{2}", guest.Name, guest.Age, guest.Tel); } Console.ReadKey(false); } } }
程序运行结果如下:
7.let子句
let子句用于在LINQ表达式中存储子表达式的计算结果。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ_let { /// <summary> /// LINQ let用来存子储表达式的计算结果 /// </summary> class Program { static void Main(string[] args) { List<GustInfo> gList = new List<GustInfo>() { new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"}, new GustInfo(){ Name="Sarah",Age=25,Tel="159********"}, new GustInfo(){ Name="Jerry",Age=35,Tel="135********"}, new GustInfo(){ Name="M&M",Age=16,Tel="136********"}, new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"}, new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"}, }; //使用let子句创建范围变量g,并通过g构建查询表达式 var query = from guest in gList let g = guest.Name.Substring(0, 1) where g == "D" || g == "J" select guest; //也可以不使用let,上面的语句等效于下 var query2 = from guest in gList where guest.Name.Substring(0, 1) == "D" || guest.Name.Substring(0, 1) == "J" select guest; foreach (var g in query) { Console.WriteLine("{0} 年龄:{1} 电话:{2}",g.Name,g.Age,g.Tel ); } Console.ReadKey(false); Console.WriteLine("不使用let,等效的语句结果"); foreach (var g in query2) { Console.WriteLine("{0} 年龄:{1} 电话:{2}", g.Name, g.Age, g.Tel); } Console.ReadKey(false); } } }
程序的运行结果如下:
8.join子句
如果一个数据源中元素的某个属性可以跟另外一个数据源的中元素的某个属性进行相等比较,那么这两个数据源可以用join子句进行关联。
join子句使用equals关键字进行相等比较,而不是常用的双等号。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LINQ_join { class Program { static void Main(string[] args) { //定义两个数据源 List<GustInfo> gList = new List<GustInfo>() { new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"}, new GustInfo(){ Name="Sarah",Age=25,Tel="159********"}, new GustInfo(){ Name="Jerry",Age=35,Tel="135********"}, new GustInfo(){ Name="M&M",Age=16,Tel="136********"}, new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"}, new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"}, }; List<GuestTitle> titleList = new List<GuestTitle>() { new GuestTitle(){Name="DebugLZQ",Title="Soft Engineer"}, new GuestTitle(){Name="DebugLZQ",Title="Team Leader"}, new GuestTitle(){Name="Sarah",Title="Test Engineer"}, new GuestTitle(){Name="Jerry",Title="Head Master"} }; //1.根据姓名进行内连接 var query = from guest in gList join title in titleList on guest.Name equals title.Name select new { Name=guest.Name ,Title=title.Title,Age=guest.Age }; foreach (var g in query) { Console.WriteLine("{0} {1} 年龄:{2}",g.Name,g.Title ,g.Age ); } Console.ReadKey(false); //前面的多个from实现相同的作用:与内连接区别在于:这个中间的操作是叉乘获得笛卡尔积 var query2=from guest in gList from title in titleList where guest.Name==title.Name select new { Name = guest.Name, Title = title.Title, Age = guest.Age }; foreach (var g in query2) { Console.WriteLine("{0} {1} 年龄:{2}", g.Name, g.Title, g.Age); } Console.ReadKey(false); //2.根据姓名进行分组连接 //根据名字分组后,得到每个名字下的全部名称 var query3 = from guest in gList join title in titleList on guest.Name equals title.Name into tgroup select new { Name=guest.Name,Titles=tgroup }; foreach (var g in query3) { Console.WriteLine(g.Name); foreach (var g2 in g.Titles) { Console.WriteLine(" {0}",g2.Title ); } } Console.ReadKey(false); //3.根据姓名进行左外连接 //无职务的输出为空缺 var query4 = from guest in gList join title in titleList on guest.Name equals title.Name into tgroup from subtitle in tgroup.DefaultIfEmpty() select new { Name=guest.Name,Title=subtitle==null?"空缺":subtitle.Title }; foreach (var g in query4) { Console.WriteLine("{0} {1} ",g.Name ,g.Title ); } Console.ReadKey(false); } } }
程序结果如下:
相关推荐
LINQ不但提供了基本查询表达式,而且还提供了数十个查询操作,如筛选操作、投影操作、集合操作、聚合操作等。通过这些操作,用户更加方便、快捷操作序列,并对序列...本章节将介绍每一种LINQ查询子句的规则和使用方法。
在实际项目中,Linq和扩展方法的组合使用能够极大地简化代码,提高可读性和维护性。通过学习和熟练掌握这些概念,开发者可以更高效地处理各种数据操作任务。在提供的`Linq及扩展方法.sln`解决方案中,可能包含了示例...
Where子句是LINQ查询表达式中最基本的部分,用于筛选满足特定条件的元素。 在VB.NET中,静态构建的Where子句通常如下所示: ```vbnet Dim numbers = {1, 2, 3, 4, 5} Dim evenNumbers = From num In numbers Where...
第3章 LINQ基本子句介绍 3.1 概述 3.2 from子句 3.2.1 单个from子句 3.2.2 复合from子句 3.2.3 多个from子句 3.3 where子句 3.3.1 常见的where子句查询 3.3.2 在where子句中使用自定义函数 3.3.3 ...
第3章 LINQ基本子句介绍 3.1 概述 3.2 from子句 3.2.1 单个from子句 3.2.2 复合from子句 3.2.3 多个from子句 3.3 where子句 3.3.1 常见的where子句查询 3.3.2 在where子句中使用自定义函数 3.3.3 ...
第3章 LINQ基本子句介绍 3.1 概述 3.2 from子句 3.2.1 单个from子句 3.2.2 复合from子句 3.2.3 多个from子句 3.3 where子句 3.3.1 常见的where子句查询 3.3.2 在where子句中使用自定义函数 3.3.3 ...
第3章 LINQ基本子句介绍 3.1 概述 3.2 from子句 3.2.1 单个from子句 3.2.2 复合from子句 3.2.3 多个from子句 3.3 where子句 3.3.1 常见的where子句查询 3.3.2 在where子句中使用自定义函数 3.3.3 ...
第3章 LINQ基本子句介绍 3.1 概述 3.2 from子句 3.2.1 单个from子句 3.2.2 复合from子句 3.2.3 多个from子句 3.3 where子句 3.3.1 常见的where子句查询 3.3.2 在where子句中使用自定义函数 3.3.3 ...
LINQ经典例子-Where、Select、SelectMany、SkipWhile子句中使用数组索引 在这个示例中,我们将学习如何使用LINQ中的Where子句来筛选数组元素,並通过使用数组索引来实现更加灵活的查询。 首先,让我们看一下Where...
LINQ提供了一系列扩展方法,适用于集合、数组和查询结果等对象,无需使用传统的SQL-like `from...where...select` 子句。 考虑以下使用查询语法的例子: \[ \texttt{var result = from n in names where n.Starts...
《LINQ入门及应用》采取以实践为主、以理论为辅的方法,首先对C#新改进的一些语法做了详细的剖析,让读者领会C#语法的新特点,为后面的学习打下基础,然后对LINQ各个子句和组件进行了实例讲解,通过一个个生动的示例...
第1章至第2章介绍了LINQ的基本语法,如隐型局部变量、Lambda表达式、查询表达式等,详细讲解了LINQ查询的基本子句和操作。第3章至第11章详细介绍了LINQ to SQL、LINQ to Objects、LINQ to DataSet和LINQ to XML 4个...
通过LINQ,开发者能够使用一致的语法进行查询,提升了代码的可读性和可维护性。 1. **LINQ简介** - LINQ允许开发者使用类似SQL的语法来操作各种类型的数据源,包括对象、SQL数据库和XML文档。 - LINQ提供了一组...
本书共分为13章,分别介绍了LINQ的基本语法、LINQ查询操作的三个步骤、LINQ查询子句的规则和使用方法、LINQ查询操作如筛选操作、投影操作、集合操作、聚合操作等。还详细介绍了使用LINQ to SQL查询和处理SQL Server...
因此,理解何时使用LINQ和何时回归基本循环很重要。 ### 10. LINQ在实际项目中的应用 在实际开发中,LINQ广泛用于数据筛选、聚合、转换等任务,特别是在大数据处理、报表生成、Web服务调用等领域。 通过"LINQ简要...
《LINQ入门及应用》采取以实践为主、以理论为辅的方法,首先对C#新改进的一些语法做了详细的剖析,让读者领会C#语法的新特点,为后面的学习打下基础,然后对LINQ各个子句和组件进行了实例讲解,通过一个个生动的示例...
上述代码首先创建一个LINQ查询,然后使用`Skip()`方法跳过当前页之前的所有记录,再用`Take()`方法获取当前页的记录。请注意,页码通常是从1开始的,但在计算时需要减1,因为数组索引从0开始。 对于数据库操作,...
- `ch02`可能涉及LINQ的基本概念和语法。 - `ch03`和`ch04`可能深入讲解查询子句和操作。 - `ch05`可能介绍LINQ to SQL的基础和对象模型。 - `ch06`和`ch07`可能涵盖更高级的主题,如数据上下文的使用、事务处理或...
- **性能考量**: 尽管Linq提供了极高的便利性,但在某些高性能要求的应用场景下,其运行效率可能不如传统查询方法。 - **复杂SQL语句**: 对于非常复杂的SQL查询需求,Linq表达式可能难以直接映射,需要借助更底层的...