第一篇 基础知识点

  • LINQ关键字
  • from 指定数据源和范围变量
  • where 根据布尔表达式(由逻辑与 或 等组成)从数据源中筛选元素
  • select 指定查询结果中的元素所具有的类型或表现形式
  • group 对对查询结果按照键值进行分组
  • into 提供一个标示符,它可以充当对 join group 或 select 子句结果的引用
  • orderby 对查询出的元素进行排序
  • join 按照两个指定匹配条件来联接俩个数据源
  • let 产生一个用于查询表达式中子表达式查询结果的范围变量
1.1 概述

LINQ的全称是Language Integrated Query,中文译成“语言集成查询”。LINQ作为一种查询技术,首先要解决数据源的封装,大致使用了三大组件来实现这个封装,分别是LINQ to Object、LINQ to ADO.NET、LINQ to XML。它们和.NET语言的关系如下:

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_范围变量
1.2 组成

LINQ的查询由3基本部分组成:获取数据源,创建查询,执行查询。

            // 1,获取数据源
            List<int> numbers = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

            // 2,创建查询
            var numQuery = from num in numbers
                           where num % 2 == 0
                           select num;

            // 3,执行查询
            foreach (var num in numQuery)
            {
                Console.WriteLine("{0,1}", num);
            }
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_其他_02
完整的查询操作
1.3 样例

代码:

static void Main(string[] args)
        {
            //获取数据源
            string[] names = { "Alen", "Zhen", "Chen","Song", "Hel", "Ken", "Aln", "Zen", "Cen", "He", "Ke", };
            //创建查询
            var queryResults = from n in names where n.StartsWith("S") select n;
            Console.WriteLine("Names beginning with S:");
            //执行查询
            foreach (var item in queryResults)
            {
                Console.WriteLine(item);
            }
            Console.Write("Program finished,press Enter/Reurn to continue:");
            Console.ReadLine();
        }
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_获取数据_03
执行结果

第二篇 语句使用方式

2.1 from子句

** 创建一个LINQ表达式必须要以from子句开头。**

2.1.1 单个form子句

样例:

 //获取数据
            string[] a = { "日本","德国","英国","美国","澳大利亚"};
            //创建查询,创建一个LINQ表达式必须要以from子句开头
            var myQuery = from n in a where n.IndexOf("国") > 0 select n;
            //执行查询
            foreach(var item in myQuery)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_范围变量_04

样例:(查询List<T>集合)
代码:

namespace LINQ查询1
{
    //定义一个信息类
    public class CustomerInfo
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Tel { get; set; }
    }
    class Test02_LINQList
    {
        static void Main(string[] args)
        {
            //使用对象和集合的初始化器
            //获取数据源
            List<CustomerInfo> customers = new List<CustomerInfo>
        {
            new CustomerInfo{Name = "杨铁心",Age = 100,Tel = "12332112332"},
            new CustomerInfo{Name = "杨康", Age = 80,Tel = "45654546565"},
            new CustomerInfo{Name = "杨过", Age = 60,Tel = "89979879789"}
        };
            //创建查询
            var query = from CustomerInfo ci in customers
                        where ci.Age >= 80
                        select ci;
            //执行查询
            foreach (CustomerInfo ci in query)
            {
                Console.WriteLine("姓名:{0} 年龄:{1} 电话:{2}",ci.Name,ci.Age,ci.Tel);
            }
            Console.ReadKey();
        }
    }
}
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_其他_05
运行结果
2.1.2 复合from子句

样例:
代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LINQ查询1
{
    public class CustomerInfo1
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public List<string> TelTable { get; set; }
    }
    class Test03_MultiFrom
    {
        static void Main(string[] args)
        {
            //获取数据源
            List<CustomerInfo1> customer = new List<CustomerInfo1>
            {
                new CustomerInfo1{Name = "郭啸天",Age = 100,TelTable = new List<string>{"123321","321123"}},
                new CustomerInfo1{Name = "郭靖",Age = 80,TelTable = new List<string>{"456654","654456"}},
                new CustomerInfo1{Name = "郭芙", Age = 60,TelTable = new List<string>{"789987","987789"}}
            };
            //创建查询
            var query = from CustomerInfo1 ci in customer
                        from tel in ci.TelTable
                        where tel.IndexOf("789987") > -1
                        select ci;
            //执行查询
            foreach (var item in query)
            {
                Console.WriteLine("姓名:{0} 年龄:{1}",item.Name,item.Age);
                foreach (var tel in item.TelTable)
                {
                    Console.WriteLine("电话:{0}",tel);
                }
            }
            Console.ReadKey();

        }
    }
}

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_范围变量_06
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_数据源_07
2.2 where 语句
  • where子句的作用就是筛选元素,除了开始和结束位置, where子句几乎可以出现在LINQ表达式的任意位置。
  • 一个LINQ表达式中可以有where子句,也可以没有;可以有一个,可以有多个;
  • 多个where子句之间的关系相当于逻辑“与”,每个where子句可以包含1个或多个逻辑表达式,这些条件成为“谓词”,多个谓词之间用布尔运算符隔开,比如逻辑“与”用&&,逻辑“或”用||,而不是用SQL中的AND或OR。
    2.2.1 常见查询
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_范围变量_08

2.2.2 自定义函数

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_获取数据_09

2.2.3 动态谓词的筛选

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_范围变量_10
2.3 select子句
2.3.1 输出查询结果
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_其他_11
2.3.2 对查询结果进行投影

代码:

 public class MyCustomerInfo
    {
        public string Name { get; set; }
        public string Tel { get; set; }
    }
    class Test04_whereExpDemo
    {
        static void Main(string[] args)
        {
            //获取数据源
            List<CustomerInfo> clist = new List<CustomerInfo>
            {
                new CustomerInfo{Name = "李白",Age = 88,Tel = "123321"},
                new CustomerInfo{Name = "杜甫", Age = 77,Tel = "456654"},
                new CustomerInfo{Name = "白居易", Age = 66,Tel = "123321"}
            };
            //定义动态的谓词数组,这个数组应该由实际运行环境生成
            string[] names = {"李白","杜甫","辛弃疾" };
            //查询在给定谓词数组里存在的客户(创建查询)
            var query = from customer in clist
                        where customer.Age < 90
                        select new MyCustomerInfo { Name = customer.Name, Tel = customer.Tel };//类型转换   
            //执行查询
            foreach (var ci in query)
            {
                Console.WriteLine("姓名:{0} 电话:{1} 类型{2}",ci.Name,ci.Tel,ci.GetType().FullName);
            }

            Console.ReadKey();
        }
    }
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_获取数据_12

个人认为就是利用select对查询结果做了一个类型转换。

2.4 Group 子句

按照语法的规定,LINQ表达式必须以from子句开头,以select或group子句结束,所以除了使用select子句外,也可以使用guoup子句来返回元素分组后的结果。group子句返回的是一个IGrouping<TKey,TElement>泛型接口的对象集合。

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_获取数据_13
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_其他_14
C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_范围变量_15
2.5 into 子句

into子句作为一个临时标识符,用于select,group,join子句中。

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_其他_16

   into子句提供了一个临时标识符,它存储了into子句前面的查询内容,使它后面的子句可以方便的使用,对其进行再次查询,投影等操作。

2.6 排序子句

2.6.1 OrderBy和OrderByDescending

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_获取数据_17

2.6.2 ThenBy和ThenByDescending

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_数据源_18
2.7 let 子句

let子句用于在LINQ表达式中存储子表达式的计算结果。let子句创建一个范围变量来存储结果,变量被创建后,不能修改或把其他表达式的结果重新赋值给它。此范围变量可以再后续的LINQ子句中使用。

C#入门经典(第6版)阅读笔记(第六篇)(LINQ)_数据源_19
2.8 join子句

如果一个数据源中元素的某个属性可以跟另一个数据源中元素的属性进行相等比较,那么这两个数据源可以用join子句进行关联。jion子句用equals关键字进行比较,而不是常见的==。