C#中Linq的入门教程

一、LINQ的体系结构

语言集成查询 (LINQ) (C#) | Microsoft 官方文档

LINQ总共包括五个部分:


程序集


命名空间


描述


LINQ to Objects


System.Core.dll


System.Linq


提供对内存中集合操作的支持


LINQ to XML


System.Xml.Linq.dll


System.Xml.Linq


提供对XML数据源的操作的支持


LINQ to SQL


System.Data.Linq.dll


System.Data.Linq


提供对Sql Server数据源操作的支持。(微软已宣布不再更新,推荐使用LINQ to Entities)


LINQ to DataSet


System.Data.DataSetExtensions.dll


System.Data


提供对离线数据集DataTable操作的支持。


LINQ to Entities


System.Core.dll 和System.Data.Entity.dll


System.Linq和System.Data.Objects


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

目前,除了以下的,还可以下载其他第三方提供程序,例如LINQ to JSON、LINQ to MySQL、LINQ to Amazon、LINQ to Flickr和LINQ to SharePoint。无论使用什么数据源,都可以通过LINQ使用相同的API进行操作。

二、 LINQ的语法

1、Query查询表达式语法

LINQ查询表达式以from子句开头,以select子句或group子句结束。

在两个子句之间,可以使用where、orderby、join、let等查询操作符。

关键字有: from 、where 、select 、group 、into 、orderby、join、let、in、on、equals、by、ascending、descending等。

  • from…in…:指定要查找的数据源以及范围变量,多个from子句则表示从多个数据源查找数据。注意:c#编译器会把“复合from子句”的查询表达式转换为SelectMany()扩展方法。
  • join…in…on…equals…:指定多个数据源的关联方式
  • let:引入用于存储查询表达式中子表达式结果的范围变量。通常能达到层次感会更好,使代码更易于阅读。
  • orderby、descending:指定元素的排序字段和排序方式。当有多个排序字段时,由字段顺序确定主次关系,可指定升序和降序两种排序方式
  • where:指定元素的筛选条件。多个where子句则表示了并列条件,必须全部都满足才能入选。每个where子句可以使用谓词&&、||连接多个条件表达式。
  • group:指定元素的分组字段。
  • select:指定查询要返回的目标数据,可以指定任何类型,甚至是匿名类型。(目前通常被指定为匿名类型)
  • into:提供一个临时的标识符。该标识可以引用join、group和select子句的结果。 
    1) 直接出现在join子句之后的into关键字会被翻译为GroupJoin。(into之前的查询变量可以继续使用) 
    2) select或group子句之后的into它会重新开始一个查询,让我们可以继续引入where, orderby和select子句,它是对分步构建查询表达式的一种简写方式。(into之前的查询变量都不可再使用)

编译器会在程序编译时转换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语句最终被转换为调用IEnumerable<T>的扩展方法,在System.Linq.Enumerable静态类中定义了N多扩展。所以只要继承与IEnumerable的类都支持Linq查询 。

2、Lambda语法

标准查询操作符

Enumberable 类定义的标准查询操作符。

  • 筛选操作符:定义返回元素的条件。 
    Where:使用谓词,返回符合条件的元素。 
    OfType<TResult>:返回符合类型的元素。
  • 投射操作符:用于把对象转换为另一个类型的新对象。 
    Select :定义根据选择器函数选择结果值的投射。 
    SelectMany:定义根据选择器函数选择结果值的投射。
  • 排序操作符:改变返回的元素的顺序。 
    Orderby: 升序排序。 
    OrderBydescending:  降序排序。 
    ThenBy 和 ThenByDescending: 二次排序。 
    Reverse: 反转集合元素。
  • 连接操作符:用于合并不直接相关的集合。 
    Join:   根据键选择器函数连接两个集合。 
    GroupJoin:   连接两个集合,并分组。
  • 组合操作符:把数据放在组中。 
    GroupBy  : 组合公共键的元素。 
    ToLookup:创建一个一对多字典,组合元素。
  • 限定(量词)操作符:元素满足指定的条件。 
    Any :部分满足谓词函数的元素。 
    All : 所有元素是否都满足谓词函数。 
    Contains:   检查某个元素是否在集合中。
  • 分区操作符:返回集合的子集。 
    Take: 从集合提取元素个数。 
    Skip :跳过指定的元素个数,提取其他元素。 
    TakeWhile :提取条件为真的元素。 
    SkipWhile:提取条件为真的元素。
  • Set操作符:返回一个集合。 
    Distinct :(去重)删除重复的元素。 
    Union: (并集)返回集合中唯一元素。 
    Intersect:(交集)返回两个集合都有的元素。 
    Except : (差集)只出现在一个集合中的元素。 
    Zip: 两个集合合并为一个元素。
  • 元素操作符:返回一个元素。 
    First:返回第一个满足条件的元素。 
    FirstOrDefault:类似First,如果未找到,返回类型的默认值。 
    Last:返回最后一个满足条件的元素。 
    LastOrDefault:类似Last,如果未找到,返回类型的默认值。 
    ElementAt:返回元素的位置。 
    ElementAtOrDefault:指定索引(超出索引,取默认值) 
    Single:返回一个满足条件的元素。如果有多个元素都满足条件,就抛出一个异常。 
    SingleOrDefault:类似Single,如果非唯一或者找不到,返回类型的默认值。
  • 聚合操作符:计算集合值。 
    Sum: 总和。 
    Count:  所有元素个数。 
    LongCount:计数(大型集合) 
    Min:  最小元素。 
    Max : 最大元素。 
    Average: 平均值。 
    Aggregate:  根据输入的表达式获取聚合值。
  • 转换操作符: 
    ToArray:变成数组 
    AsEnumerable:变成IEnumeralbe<T> 
    AsQueryable:变成IQueryable 
    ToList:变成List<T> 
    ToDictionary:变成字典 
    Cast<TResult> :转换 
    ToLookup:变一对多字典Lookup<Tkey,TElement>
  • 生成操作符: 
    Empty :空集合。 
    DefaultIfEmpty:默认值集合 
    Range:返回一系列数字。 
    Repeat: 返回始终重复一直的集合。
  • 等值操作 
    SequenceEqual:成对比较
  • 串联操作 
    Concat:串联

3、扩展方法存在对应的查询表达式关键字:

  • Where:where
  • Select:select
  • SelectMany:使用多个 from 子句
  • OrderBy:orderby
  • ThenBy:orderby …, …
  • OrderByDescending:orderby … descending
  • ThenByDescending:orderby …, … descending
  • GroupBy:group … by 或 group … by … into …
  • Join:join … in … on … equals …
  • GroupJoin: join … in … on … equals … into …

三、LINQ的特性

1、延迟执行查询

LINQ具有“延迟计算”的特性。

Linq的执行不是在Linq的赋值语句执行,而是在通过foreach遍历访问结果时执行。

var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };

var namesWithJ = (from n in names
                  where n.StartsWith("J")
                  orderby n
                  select n);

Console.WriteLine("First iteration");
foreach (string name in namesWithJ)
{
    Console.WriteLine(name);
}
Console.WriteLine();

names.Add("John");
names.Add("Jim");
names.Add("Jack");
names.Add("Denny");

Console.WriteLine("Second iteration");
foreach (string name in namesWithJ)
{
    Console.WriteLine(name);
}

返回的结果是:

两次遍历的结果不一样,说明执行并不是在Linq的定义语句执行,而是在foreach执行。

换成如下,两次执行结果就一样了。

var namesWithJ = (from n in names
                  where n.StartsWith("J")
                  orderby n
                  select n
).ToList();

2、运算符延迟计算符号

按字母顺序整理:

1、具有延迟计算的运算符

Cast,Concat,DefaultIfEmpty,Distinct,Except,GroupBy,GroupJoin,Intersect,Join,OfType,OrderBy,OrderByDescending,Repeat,Reverse,Select,SelectMany,Skip,SkipWhile,Take,TakeWhile,ThenBy,ThenByDescending,Union,Where,Zip

2、立即执行的运算符

对一系列源元素执行聚合函数的查询必须首先循环访问这些元素。CountMaxAverage 和 First 就属于此类查询。

由于查询本身必须使用 foreach 以便返回结果,因此这些查询在执行时不使用显式 foreach 语句,直接立即执行。

Aggregate,All,Any,Average,Contains,Count,ElementAt,ElementAtOrDefault,Empty,First,FirstOrDefault,Last,LastOrDefault,LongCount,Max,Min,Range,SequenceEqual,Single,SingleOrDefault,Sum,ToArray,ToDictionary,ToList,ToLookup

注意:特殊的AsEnumerable运算符,用于处理LINQ to Entities操作远程数据源,将IQueryable远程数据立即转化为本地的IEnumerable集合。若AsEnumerable接收参数是IEnumerable内存集合则什么都不做。

3、强制立即执行

若要强制立即执行任意查询并缓存其结果,可以调用 ToList<TSource> 或 ToArray<TSource> 方法。

通过调用 ToList 或 ToArray,可以将所有数据缓存在单个集合对象中。

var numQuery2 =
           (from num in numbers
            where (num % 2) == 0
            select num).ToList();
var numQuery3 =
          (from num in numbers
           where (num % 2) == 0
            select num).ToArray();

四、使用 LINQ 进行数据转换

语言集成查询 (LINQ) 不仅可用于检索数据,而且还是一个功能强大的数据转换工具。

通过使用 LINQ 查询,您可以将源序列用作输入,并采用多种方式修改它以创建新的输出序列。您可以通过排序和分组来修改该序列,而不必修改元素本身。

但是,LINQ 查询的最强大的功能是能够创建新类型。这一功能在 select 子句中实现。

例如,可以执行下列任务:

1、将多个输入联接到一个输出序列

class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string City { get; set; }
    public List<int> Scores { get; set; }
}

class Teacher
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string City { get; set; }
}

private static void Main(string[] args)
{
    //创建第一个数据源
    var students = new List<Student>() {
            new Student () {
            Age = 23,
            City = "广州",
            Name = "小C",
            Scores = new List<int> () { 85, 88, 83, 97 }
            },
            new Student () {
            Age = 18,
            City = "广西",
            Name = "小明",
            Scores = new List<int> () { 86, 78, 85, 90 }
            },
            new Student () {
            Age = 33,
            City = "梦里",
            Name = "小叁",
            Scores = new List<int> () { 86, 68, 73, 97 }
            }
        };

    //创建第二个数据源
    var teachers = new List<Teacher>() {
            new Teacher () {
            Age = 35,
            City = "梦里",
            Name = "啵哆"
            },
            new Teacher () {
            Age = 28,
            City = "云南",
            Name = "小红"
            },
            new Teacher () {
            Age = 38,
            City = "河南",
            Name = "丽丽"
            }
        };

    //创建查询
    var peopleInDreams = (from student in students
                          where student.City == "梦里"
                          select student.Name)
                .Concat(from teacher in teachers
                        where teacher.City == "梦里"
                        select teacher.Name);

    //执行查询
    foreach (var person in peopleInDreams)
    {
        Console.WriteLine(person);
    }

    Console.Read();
}

结果

小叁 
啵哆

2、选择各个源元素的子集

1. 若要只选择源元素的一个成员,请使用点运算。

var query = from cust in Customers
               select cust.City;

2. 若要创建包含源元素的多个属性的元素,可以使用具有命名对象或匿名类型的对象初始值设定项。

var query = from cust in Customer
               select new {Name = cust.Name, City = cust.City};

3、将内存中的对象转换为 XML

//创建数据源
var students = new List<Student>()
            {
                new Student()
                {
                    Age = 18,
                    Name = "小A",
                    Scores = new List<int>() {88,85,74,66 }
                },
                new Student()
                {
                    Age = 35,
                    Name = "小B",
                    Scores = new List<int>() {88,85,74,66 }
                },
                new Student()
                {
                    Age = 28,
                    Name = "小啥",
                    Scores = new List<int>() {88,85,74,66 }
                }
            };

//创建查询
var studentsToXml = new XElement("Root",
    from student in students
    let x = $"{student.Scores[0]},{student.Scores[1]},{student.Scores[2]},{student.Scores[3]}"
    select new XElement("student",
           new XElement("Name", student.Name),
           new XElement("Age", student.Age),
           new XElement("Scores", x))
);

//执行查询
Console.WriteLine(studentsToXml);

4、 对源元素执行操作

输出序列可能不包含源序列的任何元素或元素属性。

输出可能是通过将源元素用作输入参数计算出的值的序列。

//数据源
double[] radii = { 1, 2, 3 };

//创建查询
var query = from radius in radii
            select $"{radius * radius * 3.14}";

//执行查询
foreach (var i in query)
{
    Console.WriteLine(i);
}

到此这篇关于C#中Linq用法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • c#中LINQ的基本用法实例

    一.什么是LINQ LINQ(读音link)代表语言集成查询(Language Integrated Query),是.NEt框架的扩展,它允许我们用SQL查询数据库的方式来查询数据的集合,使用它,你可以从数据库.程序对象的集合以及XML文档中查询数据 下面一个简单的示例,可以查询数组中小于8的数字并输出. 一般步骤:获取数据源.创建查询.执行查询.需要注意的是,尽管查询在语句中定义,但直到最后的foreach语句请求其结果的时候才会执行 using System; using System.C

  • c#中LINQ的基本用法(二)

    目录 1.筛选 2.用索引筛选 3.类型筛选 4.复合的from子句 5.排序 6.分组 7.对嵌套的对象分组 8.内连接 9.左连接 10.组连接 11.集合操作 12.合并 13.分区 14.聚合操作符 15.转换操作符 16.生成操作符 本文主要介绍LINQ查询操作符 LINQ查询为最常用的操作符定义了一个声明语法.还有许多查询操作符可用于Enumerable类.下面的例子需要用到LINQ基础(一)(https://www.jb51.net/article/244208.htm)的一些代码

  • 全面分析c# LINQ

    大家好,这是 [C#.NET 拾遗补漏] 系列的第 08 篇文章,今天讲 C# 强大的 LINQ 查询.LINQ 是我最喜欢的 C# 语言特性之一. LINQ 是 Language INtegrated Query 单词的首字母缩写,翻译过来是语言集成查询.它为查询跨各种数据源和格式的数据提供了一致的模型,所以叫集成查询.由于这种查询并没有制造新的语言而只是在现有的语言基础上来实现,所以叫语言集成查询. 一些基础 在 C# 中,从功能上 LINQ 可分为两类:LINQ to Object 和 L

  • c#中LINQ的基本用法(一)

    LINQ(Language Integrated Query,语言集成查询),在C#语言中集成了查询语法,可以用相同的语法访问不同的数据源.LINQ提供了不同数据源的抽象层,所以可以使用相同的语法.这里主要介绍LINQ的核心原理和C#中支持C# LINQ查询的语言扩展. 1.语法 使用LINQ查询出来自巴西的所以世界冠军.这里可以使用List<T>类的FindAll()方法,但使用LINQ查询语法更简单 static void LINQQuery() { // var query = from

  • 带你一文了解C#中的LINQ

    目录 前言 LINQ的根基 IEnumerable和IEnumerator LINQ的基本用法 扩展方法在LINQ的应用:LINQ的流式语法 LINQ的查询表达式:LINQ的查询语法 LINQ的延迟执行:IQueryable 附:将内存中对象转换为 XML 参考 源码 总结 前言 本文主要的是泛谈LINQ是啥?以及常见的用法大纲如下: LINQ的那些根基 LINQ的一些基本用法 LINQ的根基 IEnumerable和IEnumerator 为啥能够被foreach? 实际上,能够被foreac

  • c#中LINQ的基本用法(三)

    一.并行LINQ System.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上.尽管Enumerable类给IEnumerable<T>接口定义了扩展方法,但ParallelEnumerable类的大多数扩展方法是ParallerQuery<TSource>类的扩展.例如,AsParallel()方法,它扩展了IEnumerable<T>接口,返回ParallelQuery<T>类,所以正常的集合类可以

  • C# LINQ的基本使用方法示例

    LINQ是什么? LINQ是Language Integrated Query(语言集成查询的缩写), 微软官方 对其的描述: 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 基本用法是什么? (我目前也只会最基本的用法..) LINQ查询操作由三个不同的操作组成: 获取数据源 创建查询 执行查询 下面我将用我学习时用的一个小例子来演示. 有两个数据源:武林高手的集合和武林绝学的集合. 我用的是两个集合,实际上不只是集合可以作为数据源 微软官方文档提到: 上例中

  • C#中Linq的入门教程

    一.LINQ的体系结构 语言集成查询 (LINQ) (C#) | Microsoft 官方文档 LINQ总共包括五个部分: 程序集 命名空间 描述 LINQ to Objects System.Core.dll System.Linq 提供对内存中集合操作的支持 LINQ to XML System.Xml.Linq.dll System.Xml.Linq 提供对XML数据源的操作的支持 LINQ to SQL System.Data.Linq.dll System.Data.Linq 提供对S

  • Go中的gRPC入门教程详解

    目录 Go GRPC 入门 1,安装包 2,gRPC 服务端 3,gRPC 客户端 4,编译运行 5,其它 GRPC Protobuf buffer 字段类型 字段规则 Protobuf gRPC 四种服务方法 编译 proto Go GRPC 入门 1,安装包 grpc golang-grpc 包提供了 gRPC 相关的代码库,通过这个库我们可以创建 gRPC 服务或客户端,首先需要安装他. go get -u google.golang.org/grpc 协议插件 要玩 gRPC,自然离不开

  • Python中的Numpy入门教程

    1.Numpy是什么 很简单,Numpy是Python的一个科学计算的库,提供了矩阵运算的功能,其一般与Scipy.matplotlib一起使用.其实,list已经提供了类似于矩阵的表示形式,不过numpy为我们提供了更多的函数.如果接触过matlab.scilab,那么numpy很好入手. 在以下的代码示例中,总是先导入了numpy: 复制代码 代码如下: >>> import numpy as np>>> print np.version.version1.6.2

  • PHP中使用curl入门教程

    概述 在我的上一篇文章"curl和libcurl简介"中简单的给大家介绍了curl相关的知识.这篇文章向大家介绍一下PHP中的curl扩展. 尽管在上一篇文章中,对curl和libcurl做了区分,也解释了某些相关的概念.同时,也知道了PHP中的curl扩展其实是对libcurl的封装.但是,在这篇文章中,为了写起来方便,将不再对这两个概念进行区分,因此文章接下来提到的curl其实是指libcurl,希望不会把大家绕糊涂. 关于PHP中curl扩展这里就不再过多介绍了,大家可以查下文档

  • Android中的AppWidget入门教程

    什么是AppWidget?AppWidget就是我们平常在桌面上见到的那种一个个的小窗口,利用这个小窗口可以给用户提供一些方便快捷的操作.本篇打算从以下几个点来介绍AppWidget: 1.如何创建一个简单的AppWidget 2.如何使得AppWidget与客户端程序交互 创建简单的AppWidget 在介绍之前给大家看一下程序运行的最后结果和项目结构图,以便大家有个整体的印象. 运行结果图: 项目结构图: 第一步: 首先在res文件夹下新建一个名字为xml的文件夹,然后在xml目录下创建一个

  • Python 机器学习库 NumPy入门教程

    NumPy是一个Python语言的软件包,它非常适合于科学计算.在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础库. 本文是对它的一个入门教程. 介绍 NumPy是一个用于科技计算的基础软件包,它是Python语言实现的.它包含了: 强大的N维数组结构 精密复杂的函数 可集成到C/C++和Fortran代码的工具 线性代数,傅里叶变换以及随机数能力 除了科学计算的用途以外,NumPy也可被用作高效的通用数据的多维容器.由于它适用于任意类型的数据,这使得NumPy可以无缝和

  • Python中强大的命令行库click入门教程

    前言 我们的游戏资源处理工具是Python实现的,功能包括csv解析,UI材质处理,动画资源解析.批处理,Androd&iOS自动打包等功能.该项目是由其他部门继承过来的,由于绝大部分代码不符合我们的业务需求,所以进行了大重构.删除了所有业务代码,仅保留了python代码框架.项目中命令行参数解析是自己实现的,极其不优雅,也忍了这么久.打算找时间用click重写.所以最近学习了click,下面本文的内容是click的入门教程,初学者们可以来一起学习学习. 官网镜像地址: http://click

  • Java8中的lambda表达式入门教程

    1.基本介绍 lambda表达式,即带有参数的表达式,为了更清晰地理解lambda表达式,先上代码: 1.1 两种方式的对比 1.1.1 方式1-匿名内部类 class Student{ private String name; private Double score; public Student(String name, Double score) { this.name = name; this.score = score; } public String getName() { ret

  • dotNet中的反射用法入门教程

    本文实例讲述了dotNet中的反射用法.分享给大家供大家参考,具体如下: 参考MSDN: ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpcondiscoveringtypeinformationatruntime.htm 提纲: 1. 什么是反射 2. 命名空间与装配件的关系 3. 运行期得到类型信息有什么用 4. 如何使用反射获取类型 5. 如何根据类型来动态创建对象 6. 如何获取方法以及动态调用方法 7. 动态创

  • vue项目中使用ts(typescript)入门教程

    目录 1.引入Typescript 2.配置文件webpack配置 3.让项目识别.ts 4.vue组件的编写 data()中定义数据 props传值 完整代码案例 最近项目需要将原vue项目结合ts的使用进行改造,这个后面应该是中大型项目的发展趋势,看到一篇不错的入门教程,结合它并进行了一点拓展记录之.本文从安装到vue组件编写进行了说明,适合入门. 1.引入Typescript npm install vue-class-component vue-property-decorator --

随机推荐