一、什么是LINQ

LINQ是Language Integrate Query的缩写,意为语言集成查询,是微软在.Net Framework 4.5版中推出的主要特性之一。

它为开发人员提供了统一的数据查询模式,并与.Net开发语言(如C#和VB.Net)集成,很大程度上简化了数据查询的编码和调试工作,提供了数据查询的性能。

LINQ中查询表达式访问的是一个对象,而该对象可以表示为各种类型的数据源。比如SQL Server数据库,XML文档,ADO.NET数据集,以及内存中的数据集合等。

在.NET类库中,LINQ相关类库都在System.Linq命名空间中,该命名空间提供支持使用LINQ进行查询的类和接口,其中主要是以下两个接口和两个类:

IEnumerable<T>接口:它表示可以查询的数据集合,一个查询通常是逐个对集合对象中的元素进行筛选操作,返回一个新的IEnumerable<T>对象,用来保存查询结果。

IQueryable<T>接口:它继承自IEnumerable<T>接口,表示一个可以查询的表达式目录树。

Enumerable类:它通过对IEnumerable<T>提供扩展方法,实现LINQ标准查询运算。包括过滤、导航、排序、关联、求和、求最大值、求最小值等操作。

Queryable类:它通过对IQueryable<T>提供扩展方法,实现LINQ标准查询运算。包括过滤、导航、排序、关联、求和、求最大值、求最小值等操作。

根据数据源类型,可以将LINQ技术分为以下几个主要技术方向:

1.LINQ to Object:数据源为实现了接口IEnumerable<T>和IQueryable<T>的内存数据集合,这也是LINQ的基础,本文将介绍着方面的内容。

2.LINQ to ADO.NET:数据源为ADO.NET数据集,这里将数据库中的表结构映射到类结构,并通过ADO.NET从数据库中获取数据集到内存,通过LINQ进行数据查询。

3.LINQ to XML:数据源为XML文档,这里通过XElement、XAttribute等类将XML文档数据加载到内存中,通过LINQ进行数据查询。

二、LINQ查询表达式

在进行LINQ查询的编写之前,首先要了解查询表达式。查询表达式是LINQ查询的基础,也是最常用的编写LINQ查询的方法。查询表达式由查询关键字和对应的操作数组成。其中,查询关键字是常用的查询运算符。

在C# 3.0中可以直接使用的查询关键字和功能如下表:

1.用from子句指定数据源

每个LINQ查询表达式都以from子句开始,from子句包括以下两个功能。

(1)指定查询将采用的数据源

(2)定义一个本地变量,表示数据源中单个数据

单个from子句的编写格式为: from localVar in dataSource,其中,dataSource表示数据源,localVar表示单个元素。

示例代码如下:

            int[] array = { , , , ,  };
var query = from item in array
select item;
foreach (var item in query)
{
Console.WriteLine(item);
}

2.使用select子句指定目标数据源

select子句指定在执行查询是产生的结果类型,其格式为:select element,其中elment参数指定查询结果中元素的类型及初始化方式。

在进一步介绍select子句之前,先介绍一下本文示例中要用到的实体类:

public class LessonScore
{
/// <summary>
/// 课程成绩
/// </summary>
public float Score { get; set; }
/// <summary>
/// 课程名称
/// </summary>
public string Lession { get; set; } public override string ToString()
{
return string.Format("{0}-----{1}分",Lession,Score);
}
} public class Student
{
/// <summary>
/// 学生名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 学生性别
/// </summary>
public string XingBie { get; set; }
/// <summary>
/// 学生年龄
/// </summary>
public int Age { get; set; } public List<LessonScore> Scores { get; set; } public override string ToString()
{
 return string.Format("{0}---{1}---{2}",Name, XingBie,Age);
}
}

select子句中要选择的目标类型不仅可以为数据源中的元素,还可以是该元素的不同操作结果,包括属性、方法和运算等。示例代码如下:

              Student[] students = {
new Student() {Name="乔峰",Age=,XingBie="男" },
new Student() {Name="欧阳修",Age=,XingBie="男" },
new Student() {Name="王五",Age=,XingBie="男" },
new Student() {Name="王丹",Age=,XingBie="女" },
new Student() {Name="倾国倾城",Age=,XingBie="女" }
};
var query1 = from student in students
select student;//整个元素作为查询结果
foreach (var item in query1)
{
Console.WriteLine(item);
} var query2 = from student in students
select student.Name;//元素的属性作为查询结果
foreach (var item in query2)
{
Console.WriteLine(item);
} var query3 = from student in students
select student.Name.Length;
foreach (var item in query3)
{
Console.WriteLine(item);
}

在某些特殊的场合下,往往查询结果只是临时使用一下,而查询结果的数据包括很多字段,并非一个简单的属性、方法返回值等。这时,可在select子句中使用匿名类型来解决这类问题。

示例代码如下:

                //返回数据源中学生的姓名、年龄、姓名的长度
//使用匿名类型方式返回
var query4 = from student in students
select new {student.Name,student.Age,NameLen = student.Name.Length };
foreach (var item in query4)
{
Console.WriteLine(item);
}

3.使用where子句指定筛选条件

通常一个LING查询不会如前面的示例代码那么简单,通常还需要对数据源中的元素进行过滤。只有符合条件的元素,才能参与查询结果的计算。

LINQ中,where子句格式为:where expression,其中,expression是一个逻辑表达式,返回布尔值。

where子句中的条件表达式,可以用&&和||指定多个条件的逻辑运算关系。其中,&&表示逻辑并,||表示逻辑或。

示例代码:

                int[] array = { ,,,,,,,,,};
var query1 = from item in array //查询array中所以大于15的元素
where item >
select item; foreach (var item in query1)
{
Console.Write("{0}, ",item);
}
Console.WriteLine(); var query2 = from item in array //查询array中所以大于10小于40的元素
where item > && item <
select item; foreach (var item in query2)
{
Console.Write("{0}, ", item);
}
Console.WriteLine(); var query3 = from item in array //查询array中小于10或者大于40的元素
where item < || item >
select item; foreach (var item in query3)
{
Console.Write("{0}, ", item);
}

4.使用orderby子句进行排序

在一些场合,还需要对查询结果进行排序。在LINQ中,通过orderby子句对查询结果进行排序操作。

orderby子句格式为:orderby element [ascending|descending],其中element是要进行排序的字段,可以是数据源中的数据,也可以是对元素操作的结果。

[ascending|descending]是排序类型,ascending为升序,descending为降序,默认请客下为ascending。

示例代码:

               int[] array = { , , , , , , , , ,  };
var query1 = from item in array //升序
orderby item
select item;
foreach (var item in query1)
{
Console.Write("{0}, ", item);
}
Console.WriteLine(); var query2 = from item in array //降序
orderby item descending
select item;
foreach (var item in query2)
{
Console.Write("{0}, ", item);
}
Console.WriteLine();

在LINQ中,orderby子句可以同时指定多规排序元素,还可以为每个元素指定独立的排序类型。orderby语句后的第一个排序元素为主要排序,第二个为次要排序,以此类推。

示例代码如下:

               Student[] students = {
new Student() {Name="乔峰",Age=,XingBie="男" },
new Student() {Name="欧阳修",Age=,XingBie="男" },
new Student() {Name="王五",Age=,XingBie="男" },
new Student() {Name="王丹",Age=,XingBie="女" },
new Student() {Name="倾国倾城",Age=,XingBie="女" }
};
//主要按姓名长度从小到大,次要按年龄从大到小
var query3 = from stu in students
orderby stu.Name.Length ascending, stu.Age descending
select stu;
foreach (var item in query3)
{
Console.WriteLine(item);
}

5.使用group子句进行分组

在LINQ中,用group子句实现对查询结果的分组操作。group子句的常用格式为:group element by key。其中,element表示作为查询结果返回的元素,key表示分组条件。

group子句返回类型为IGrouping<TKey,TElement>的查询结果。

示例代码如下:

                Student[] students = {
new Student() {Name="乔峰",Age=,XingBie="男" },
new Student() {Name="欧阳修",Age=,XingBie="男" },
new Student() {Name="王五",Age=,XingBie="男" },
new Student() {Name="王丹",Age=,XingBie="女" },
new Student() {Name="倾国倾城",Age=,XingBie="女" }
};
//按学生性别分组
var query1 = from stu in students
group stu by stu.XingBie;
foreach (var grp in query1)
{
Console.WriteLine(grp.Key);
foreach (var item in grp)
{
Console.WriteLine(item);
}
}
//按多条件分组,按性别和年龄分组
var query2 = from stu in students
group stu by new { stu.XingBie, stu.Age };
foreach (var grp in query2)
{
Console.WriteLine("{0}---{1}",grp.Key.XingBie,grp.Key.Age);
foreach (var item in grp)
{
Console.WriteLine(item);
}
}

有时候需要对分组的结果进行排序、再次查询等操作。这就需要使用into关键字将group查询的结果保存到一个临时变量,并且必须使用select子句对其进行重新查询。

into关键字语法为:group element by key into grp,其中,tmpGrp表示一个本地变量,用来临时保存group产生的结果,提供后面的LINQ子句使用。

示例代码如下:

             Student[] students = {
new Student() {Name="乔峰",Age=,XingBie="男" },
new Student() {Name="欧阳修",Age=,XingBie="男" },
new Student() {Name="王五",Age=,XingBie="男" },
new Student() {Name="王丹",Age=,XingBie="女" },
new Student() {Name="倾国倾城",Age=,XingBie="女" }
}; var query3 = from stu in students
group stu by stu.Age into grp
orderby grp.Key descending
select grp;
foreach (var grp in query3)
{
Console.WriteLine("{0}岁的学生:", grp.Key);
foreach (var item in grp)
{
Console.WriteLine(item);
}
}

LINQ查询基础的更多相关文章

  1. C#语法之Linq查询基础二

    上篇C#语法之Linq查询基础一基本把Linq介绍了一下,这篇主要是列举下它的几个常见用法. 在用之前先准备些数据,新建了两个类Student.Score,并通过静态方法提供数据. using Sys ...

  2. C#语法之Linq查询基础一

    Linq做.Net开发的应该都用过,有些地方很复杂的逻辑用Linq很方便的解决.对于Linq to object.Linq to xml.Linq to sql.Linq to Entity(EF)都 ...

  3. C#基础:LINQ 查询函数整理

    1.LINQ 函数   1.1.查询结果过滤 :where() Enumerable.Where() 是LINQ 中使用最多的函数,大多数都要针对集合对象进行过滤,因此Where()在LINQ 的操作 ...

  4. C#3.0新增功能09 LINQ 基础02 LINQ 查询简介

    连载目录    [已更新最新开发文章,点击查看详细] 查询 是一种从数据源检索数据的表达式. 查询通常用专门的查询语言来表示. 随着时间的推移,人们已经为各种数据源开发了不同的语言:例如,用于关系数据 ...

  5. C#3.0新增功能09 LINQ 基础04 基本 LINQ 查询操作

    连载目录    [已更新最新开发文章,点击查看详细] 本篇介绍 LINQ 查询表达式和一些在查询中执行的典型操作. 获取数据源 在 LINQ 查询中,第一步是指定数据源. 和大多数编程语言相同,在使用 ...

  6. C#3.0新增功能09 LINQ 基础06 LINQ 查询操作中的类型关系

    连载目录    [已更新最新开发文章,点击查看详细] 若要有效编写查询,应了解完整的查询操作中的变量类型是如何全部彼此关联的. 如果了解这些关系,就能够更容易地理解文档中的 LINQ 示例和代码示例. ...

  7. LINQ查询表达式(1) - 查询表达式基础

    LINQ包括五个部分:LINQto Objects.LINQ to DataSets.LINQ to SQL.LINQ to Entities.LINQ to XML. 什么是查询?它有什么用途? “ ...

  8. .NET LINQ查询语法与方法语法

    LINQ 查询语法与方法语法      通过使用 C# 3.0 中引入的声明性查询语法,介绍性 LINQ 文档中的多数查询都被编写为查询表达式. 但是,.NET 公共语言运行时 (CLR) 本身并不具 ...

  9. LINQ 查询表达式(C# 编程指南)

    语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上.  借助于 LINQ,查询现在 ...

随机推荐

  1. 记录python之递归函数

    函数move(n,a,b,c)的定义是将n个圆盘从a借助b移动到c. def move(n,a,b,c): if n==1: print a,'-->',c move (n-1,a,c,b) p ...

  2. JAVA jsp page指令的属性 errorPage 和isErrorPage

    >errorPage指定当前页面出现错误的实际响应页面是什么, 其中“/” 表示的是当前WEB应用的根目录 <% page errorPage="/error.jsp" ...

  3. #error 、 #line 和 #pragma 的使用

    1. #error 的用法 (1)#error 是一种预编译器指示字,用于生成一个编译错误消息 (2)用法:#error message //注意:message 不需要用双引号包围 (3)#erro ...

  4. Android实战简易教程-第二十八枪(Uri转String型实例)

    接上一篇文章.我们能够轻易的获取所选图片的uri,那么我们考虑怎样将获取的uri转换成String型的地址呢? 接下来我们通过实例来研究.布局文件和上篇(二十七枪)一致,我们就不再列出,直接看Main ...

  5. 移植u-boot-2014.4到S5PV210/TQ210(完整)

    本文很多其它的是教会大家怎样学习 1.1   概述 1.2   u-boot配置过程分析 1.3   u-boot编译过程分析 1.4   SPL 1.5   加入自己的单板 1.6   移植u-bo ...

  6. Ryu基本操作的REST API调用演示样例

    import urllib2 import json def get_all_switches(): url = "http://127.0.0.1:8080/v1.0/topology/s ...

  7. 小米净水器与小区过滤价格水对照.xls

    总结:要是一天用水量为7升下面.还是用小区的过滤水为好,合算. 假设过滤水需求量大,可能小米的净水器比較好.当然,小区的要天天去接.要求风雨无阻的. 这点小米的随用随接就更好. 注意一点,小米的还要用 ...

  8. hdoj--5569--matrix(动态规划)

    matrix Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Sub ...

  9. Mysql优化理论知识

    参考文章 http://blog.51cto.com/lizhenliang/2095526 ()硬件优化 如果有条件一定要SSD固态硬盘代替SAS机械硬盘,将RAID级别调整为RAID1+,相对于R ...

  10. 2013亚洲区域赛长沙站 ZOJ 3732 Graph Reconstruction

    题目链接 Graph Reconstruction 题意 给你无向图每个点的度数, 问是否存在唯一解, 存在输出唯一解, 多解输出两个, 无解输出IMPOSSIBLE 思路 这里用到了 Havel-H ...