LINQ查询

LINQ查询

LINQ能够解决的问题

.NET平台开发中一直存在的情况:

  1. 面向对象编程语言与数据库访问方法长期分离,以嵌入式方式开发

    嵌入式SQL语句没有任何提示,很容易出错

  2. 编程语言中的数据类型与数据库中的数据类型完全是两套体系

    例如:C#中字符串string在SQL中使用varchar/Nvarchar/char来表示

  3. SQL和XML都有各自的查询语言,而对象没有自己的查询语言

    例如:要从一个List< T>集合或者数组中找到符合要求的元素非常困难。

LINQ查询重点解决以上问题

LINQ是什么

LINQ(Language Integrated Query)

语言集成查询

  1. 是微软公司提供的一项新技术,能够将查询功能直接引入到C#、VB.NET等编程语言中

  2. 查询操作可以通过编程语言自身来表示,而不是嵌入字符串SQL语句

LINQ的组成

  1. LINQ to Objects 主要负责对象的查询

  2. LINQ to XML 主要负责XML的查询

  3. LINQ to ADO.NET 主要负责数据库的查询

    1. LINQ to SQL (目前已经没人使用)

    2. LINQ to DataSet

    3. LINQ to Entities (重点学习)

LINQ的命名空间

  1. System.Linq;该命名空间已经由系统自动引入

  2. 因此微软默认建议多使用Linq技术查询

LINQ的组成架构

不采用LINQ技术的查询

static void Main(string[] args)
        {
            //1.从数组中拿到所有的偶数
            int[] nums = { 1, 22,18,2, 3, 5, 7, 6, 8, 9, 23, 12 };
            List<int> list = new List<int>();
            foreach (int item in nums)
            {
                if (item%2==0)
                {
                    list.Add(item);
                }
            }
            list.Sort();
            list.Reverse();
            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i]);
            }
            Console.ReadLine();
        }

采用LINQ技术进行查询      

int[] nums = { 1, 22, 18, 2, 3, 5, 7, 6, 8, 9, 23, 12 };
            var list = from item in nums
                       where item % 2 == 0
                       orderby item descending
                       select item;
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

LINQ查询方法

获取数据方法

扩展方法:Select()

  1. Select()是一个泛型扩展方法

  2. Select()方法使用的时候,要求传递一个委托实例(委托实例就是一个方法)

Select()方法应用

  int[] nums = { 1, 22, 18, 2, 3, 5, 7, 6, 8, 9, 23, 12 };
            var list = nums.Select(item=>item*2);
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
  1. Select()方法里面是一个Lambda表达式

  2. 返回结果是一个迭代[隐式循环]器(Iterator)

  3. 不论数组还是集合都可以使用Select()扩展方法

筛选数据方法

扩展方法:Where()

  1. Where()方法是一个扩展泛型方法

  2. Where()方法使用的时候要求传递一个委托实例,但该实例是一个判断条件,因此返回的类型必须是bool类型

Where()方法应用

   var list = nums.Where(item => item % 2 != 0).Select(item=>item*2);
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

“链式编程”:在一个方法完成之后可以继续紧接着调用方法

注意:链式编程在每个环节之后能否继续链式要考虑这个环节的结果是否是集合

排序数据方法

扩展方法:OrderBy()

  1. OrderBy()是一个扩展方法

  2. OrderBy()里面的参数要求传递一个排序字段,默认按照升序排序

  3. 如果需要降序排列可以使用OrderByDescending方法

OrderBy()方法应用

 var list = nums.Where(item => item % 2 == 0)
                .Select(item => item * 2)
                .OrderBy(item=>item);
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
            string[] arry = { "张三","李四","王五","赵六","陈七","宋八","杜九"};

​
            var list = arry.Select(item => item).OrderBy(item => item.Substring(1,1));
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

分组数据方法

扩展噶GroupBy()

  1. GroupBy()是一个扩展方法

  2. GroupBy()里面的参数要求传递一个分组字段

GroupBy()方法应用

   var list = arry.Select(item => item).GroupBy(item => item.Substring(0, 1));
            foreach (var item in list)
            {
                Console.WriteLine("---------------------------");
                Console.WriteLine("分组字段:" + item.Key);
                foreach (var i in item)
                {
                    Console.WriteLine(i);
                }
            }

LINQ查询形式

查询步骤:获取数据源、定义查询、执行查询

结论:

  1. 定义查询后,查询并没有立即执行,而是直到需要枚举结果(遍历)的时候才真正执行查询工作

  2. 这种方式称为“延迟执行(deferred execution)”

可以使用“聚合扩展方法”,返回单一结果,强制查询立即执行

LINQ查询的两种形式

查询方法方式

Method Syntax

  1. 主要利用System.Linq.Enumerable类中定义的扩展方法和Lambda表达式方式查询

  2. 在此之前所用的查询都是这种方法

查询语句方法

Query Syntax

  1. 一种更接近SQL语法的查询方式,可读性更好

  2. 查询语句最后还是要被翻译成查询方法

  string[] arry = { "张三","李四","王五","赵六","陈七","宋八","杜九", "张无极", "李世民", "王超", "赵四" , "张三丰", "李渊", "王子", "赵敏" };
            var list = from item in arry
                       group item by item.Substring(0,1);
            foreach (var item in list)
            {
                Console.WriteLine("---------------------------");
                Console.WriteLine("分组字段:" + item.Key);
                foreach (var i in item)
                {
                    Console.WriteLine(i);
                }
            }

和查询方法的查询结果完全一致

两种结果比较

  1. CLR本身并不理解查询语句,他只理解查询方法

  2. 编译器只负责编译时将查询语句翻译为查询方法

  3. 大部分查询方法都有对应的查询语句形式:select()对应select、OrderBy()对应order...by....

  4. 部分查询方法目前在C#中还没有对应的语句,例如Count()和Max()等,这时只能采用以下方案

    1. 查询方法

    2. 查询方法+查询方法的混合方式

    一般情况下,建议使用可读性强的查询语句查询

LINQ查询子句

查询表达式

  1. 是一种用查询语法表示的表达式,由一组类似于SQL的语法编写的句子组成

  2. 每一个子句可以包含一个或多个C#表达式

 int[] nums = { 1, 22, 18, 2, 3, 5, 7, 6, 8, 9, 23, 12 };
            var list = from item in nums
                       where item % 2 != 0
                       orderby item * 2 descending
                       select item * 2;
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

LINQ查询表达式必须以from子句开头,并且必须以select或者group子句结束,中间可以添加多个子句

查询子句

  1. from子句:指定查询操作的数据源和范围变量

  2. where子句:筛选元素的逻辑条件,返回值必须是一个bool类型

  3. select子句:指定查询结果的类型和表现形式

  4. orderby子句:对查询结果进行排序(升序或降序)

  5. group... by...子句:对查询结果进行分组

  6. into子句:提供一个临时标识符,该表示可以充当对join、group、select子句结果的引用

  7. join子句:连接多个查询操作的数据源

  8. let子句:引入用于存储查询表达式中的子表达式结果的范围变量

from子句

  1. LINQ查询表达式必须包含from子句,并且必须以from子句开始

  2. from子句指定的数据源类型必须为IEnumerable、IEnumerable< T>或者两者的派生类型(例如:数组、List< T>、ArrayList等)

    //nums:数据源
    //item:范围变量:一般表示数据源中的每一个元素
    var list = from item in nums
                           where item % 2 != 0
                           orderby item * 2 descending
                           select item * 2;

     

  3. 数据源:

    1. 如果数据源是泛型类型,则编译器可以自动推断出范围变量的类型

    2. 如果数据源是非泛型类型,如ArrayList,则必须显示的指定范围变量的数据类型

         ArrayList nums = new ArrayList();
                  nums.AddRange(new int[] { 1,3,6,9,2,8,7});
                  var list = from int item in nums
                             where item % 2 != 0
                             orderby item * 2 descending
                             select item * 2;
                  foreach (var item in list)
                  {
                      Console.WriteLine(item);
                  }

       

     

from复合子查询

如果数据源本事是一个序列的元素还包含子数据源,如果查询子数据源中的元素,则需要复合from子句

  public class Student
    {
        public int StuId { get; set; }
        public string StuName { get; set; }
        public int StuAge { get; set; }
        public List<int> StuScore { get; set; }
    }
            Student stu1 = new Student() { StuId = 10000, StuAge = 18, StuName = "张三", StuScore = new List<int>() { 89, 68, 76 } };
            Student stu2 = new Student() { StuId = 10001, StuAge = 20, StuName = "李四", StuScore = new List<int>() { 78, 88, 86 } };
            Student stu3 = new Student() { StuId = 10002, StuAge = 21, StuName = "王五", StuScore = new List<int>() { 90, 75, 82 } };
            List<Student> stulist = new List<Student>() { stu1, stu2, stu3 };
            //查询成绩中有一门成绩高于89分的所有学员
            var res = from item in stulist
                      from score in item.StuScore
                      where score > 89
                      select item;
            foreach (var item in res)
            {
                Console.WriteLine("成绩中包含89分以上的学员有:{0}",item.StuName);
            }

from多个子句查询

如果LINQ查询表达式包含两个或两个以上的独立数据源时,可以使用多个from子句查询所有数据源中的数据

 var res = from item1 in stulist1
                      where item1.StuAge > 20
                      from item2 in stulist2
                      where item2.StuAge > 20
                      select new { item1, item2 };
            foreach (var item in res)
            {
                Console.WriteLine("年龄大于20的学员有:{0}",item.item1.StuName);
                Console.WriteLine("年龄大于20的学员有:{0}", item.item2.StuName);
            }

其他子句

where子句

  1. 用于指定筛选元素的逻辑条件

  2. 一个查询表达式可以不包含where子句

  3. 如果查询表达式包含where子句,则where子句不能放在最后一个子句

select子句

  1. 用于指定查询结果的类型和表现形式

  2. LINQ查询表达式或者select子句结束或者以group子句结束

group子句

  1. 用于对查询结果进行分组

  2. 返回元素类型为Igrouping< Tkey,TElement >对象序列

orderby子句

  1. 用于对查询结果排序,默认“升序”

  2. 在排序字段后面加上descending可以实现降序

LINQ高级查询

高级查询方法

聚合类

Count(),Max()/Min(),Average()

排序类

ThenBy()

分区类

Take(),TakeWhile(),Skip(),WkipWhile()

集合类

Distinct()

生成类

Range(),Repeat()

Count方法

返回集合项的数目,集合中的元素数量

Max/Min方法

求集合中的最大值或者最小值

Average方法

求集合中所有数据的平均值

Sum方法

求集合的所有数的总和

  int[] nums = { 1, 22, 18, 2, 3, 5, 7, 6, 8, 9, 23, 12 };
​
            var res = (from item in nums
                       select item).Count();
            Console.WriteLine("集合中总共有:"+res);
​
            var res2 = (from item in nums
                        select item).Max();
            Console.WriteLine("集合中最大值:" + res2);
            var res3=(from item in nums
                        select item).Min();
            Console.WriteLine("集合中最小值:" + res3);
            var res4= (from item in nums
                    select item).Average();
            Console.WriteLine("集合中平均值:" + res4);
​
            var res5 = (from item in nums
                        select item).Sum();
            Console.WriteLine("集合中总和:" + res5);
​
            var res6 = (from item in nums
                        select item).First();
            Console.WriteLine("集合中第一个:" + res6);

ThenBy方法

提供复合排序条件,为排序方法提供更多的排序字段        

   var list = from item in stulist1
                       orderby item.StuAge,item.StuName
                       select item;
            foreach (var item in list)
            {
                Console.WriteLine(item.StuName);
            }
            var list = stulist1.OrderBy(item => item.StuAge).ThenBy(item => item.StuName);

Take方法

从集合中的开头提取指定数量的元素

Skip方法

跳过指定数量的元素,并获取剩余数量的元素

TakeWhile方法

只要满足指定的条件,就会返回序列的元素,然后跳过剩余的元素

SkipWhile方法

只要满足指定的条件,就会跳过序列中的元素,然后返回剩余的元素          

  int[] nums = { 1, 22, 2, 18, 3, 5, 7, 6, 8, 9, 23, 12 };
​
            var list = nums.Take(5);
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("--------------");
            var list2 = nums.Skip(8);
            foreach (var item in list2)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("--------------");
            var list3 = nums.TakeWhile(item=>item%3!=0);
            foreach (var item in list3)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("--------------");
            var list4 = nums.SkipWhile(item => item % 3 != 0);
            foreach (var item in list4)
            {
                Console.WriteLine(item);
            }

Distinct方法

去掉集合中的重复元素            

int[] list = { 1, 2, 3, 4, 1, 2, 3, 6, 7, 8 };
            var res = list.Distinct();
            foreach (var item in res)
            {
                Console.WriteLine(item);
            }

Range方法

生成一个整数序列

Repeat方法

生成一个重复项的序列

  1. 这两个方法不是扩展方法,而是普通的静态方法

  2. Range只能产生整数序列

  3. Repeat可以产生泛型序列

  4. 所有的查询方法都存放在System.Linq.Enumerable静态类中        

   var list1 = Enumerable.Range(1,9);
            var list2 = Enumerable.Repeat(new int[] { 1,2,3},5);
            foreach (var item in list1)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("------------------------");
            foreach (var item in list2)
            {
                Console.WriteLine(item);
            }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#中,LINQ(Language Integrated Query)是一种用于查询和操作各种数据源的语言集成查询技术。LINQ提供了一种统一的查询语法,可以用于查询对象集合、数据库、XML文档等各种数据源。 在给出的引用中,引用\[1\]展示了如何使用LINQ进行查询结果排序。在示例中,通过使用`orderby`关键字,可以按照指定的字段进行排序。例如,`orderby e.LevelNum, e.Name, e.Age descending`表示按照级别、姓名和年龄进行排序,其中`descending`表示降序排序。 引用\[2\]展示了如何使用LINQ进行联合查询。通过使用`from`关键字和`select`关键字,可以将两个集合进行联合查询,并输出结果。例如,`from e in empArray from l in empLeArray select new { e, l }`表示将`empArray`和`empLeArray`两个集合进行联合查询,并输出结果。 引用\[3\]展示了LINQ支持的查询环境之一,即对象集合。在示例中,通过创建`List<string>`、`Dictionary<string, string>`、`ArrayList`和`Hashtable`等对象集合,可以在LINQ中进行查询操作。 综上所述,C#中的LINQ查询可以通过使用`orderby`关键字进行结果排序,使用`from`和`select`关键字进行联合查询,并支持在对象集合中进行查询操作。 #### 引用[.reference_title] - *1* *2* *3* [C#之Linq查询表达式](https://blog.csdn.net/weixin_49251429/article/details/123671040)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值