• c# 之linq——小白入门级


    通过本文需要掌握的关于linq的知识点为:

    • linq的基本概念及其特点

    • linq中常见操作及使用

    • linq常见的方法查询

     

    1 Linq基本概念

    1.1 ling定义

    Linq(Language Integrated Query),语言集成查询,是一种使用类似SQL语句操作多种数据源的功能。如,我们可以使用c#查询access数据库、.net数据集、xml文档以及实现了IEnumerable或IEnumerable<T>接口的集合类(如List,Array,SortedSet,Stack,Queue等,可以进行遍历的数据结构都会集成该类)。从.net framework3.5中开始引入,能够提升程序数据处理能力和开发效率,具有集成性、统一性、可扩展性、抽象性、说明式编程、可组成型、可转换性等优势。

    1.2 linq提供的程序

    • Linq to Object。提供程序查询内存中的集合和数组。

    • Linq to DataSet。提供程序查询ADO.NET数据集中的数据。

    • Linq to SQL。提供程序查询和修改Sql Server数据库中的数据,将应用程序中的对象模型映射到数据库表。

    • Linq to Entities。使用linq to entities时,会在后台将linq语句转换为sql语句与数据库交互,并能提供数据变化追踪。

    • Linq to XML。提供程序查询和修改XML,既能修改内存中的xml,也可以修改从文件中加载的。

     

    2 Linq查询

    linq查询包括两种方式,一是语句查询,二是方法查询。语句查询使用较多,也更容易理解,微软官网推荐使用。下面介绍语句查询的子句使用。

    2.1 from子句

    用来标识查询的数据源。基本语法格式为:

    from 迭代变量 in 数据源
    

    首先,通过以下简单示例,给出from用法

    static void Main(string[] args)
    {
        var nums = new int[] {56,97,98,57,74,86,31,90};
            var queryInfo = from num in nums select num;//num为数据中的每个元素(相当于foreach中迭代变量)
            var numStr = string.Empty;
        foreach (var item in queryInfo) 
        {
              numStr += item + " ";
        }
        Console.WriteLine($"数据元素包括:{numStr}");
    }

    运行结果如下图:

     注: 查询表达式在循环访问查询变量时(如上述示例中foreach),才会执行。

    2.2 select子句

    select子句,基于查询结果返回需要的值或字段,并能够对返回值指定类型。对任意想要获取到返回结果的linq语句,必须以select或group结束。示例如下:

    // 基础类准备
    public class User
    {
          public string UserId { get; set; }
          public string UserName { get; set; }
            public string UserPhone { get; set; }
    }
    public class Order
    {
          public string Id { get; set; }
          public string UserId { get; set; }
          public string OrderCode { get; set; }
    }
     static void Main(string[] args)
     {
       var user1 = new User() {UserId = "1", UserName = "张三", UserPhone = "1234567997"};
       var user2 = new User() {UserId = "2", UserName = "李四", UserPhone = "18335789789"};
       var users = new List<User>() { user1, user2 };
       var order1 = new Order {Id = "1", UserId = "1", OrderCode = "orderCode001"};
       var order2 = new Order {Id = "2", UserId = "1", OrderCode = "orderCode002"};
       var orders = new List<Order>{order1, order2};
    
       List<string> queryInfo = (from user in users select user.UserName).ToList();
       foreach (var item in queryInfo)
       {
         Console.WriteLine(item);
       }
    
       var queryInfos = (from user in users select new {name = user.UserName, phone = user.UserPhone}).ToList();
       foreach (var item in queryInfos)
       {
         Console.WriteLine(item);
       }
     }

    运行结果如下:

    2.3 where子句

    where子句用来指定筛选的条件,与sql或mysql查询语句中的where功能一样。通过where子句获取到满足条件的结果。示例如下:

    static void Main(string[] args)
    {
       var user1 = new User() {UserId = "1", UserName = "张三", UserPhone = "1234567997"};
       var user2 = new User() {UserId = "2", UserName = "李四", UserPhone = "18335789789"};
       var users = new List<User>() { user1, user2 };
    
       var whereQuery = from user in users where user.UserId == "1" select user;
       foreach (var item in whereQuery)
       {
         Console.WriteLine($"id =1 的用户姓名为:{item.UserName},手机号为:{item.UserPhone}");
       }
    }

    运行结果如下图

     

    2.4 order by

    orderby用来排序,与sql或mysql中orderby的功能相同,使得返回结果可以根据某字段或某种规则实现升序或降序排列。linq中语句默认展示为升序,降序使用【orderby 表达式 descending】.

    static void Main(string[] args)
    {
            var scores = new int[] { 56,97,98,57,74,86,31,90};
          //var orderQuery = from score in scores orderby score select score;//升序
              var orderQuery = from score in scores orderby score descending select score;//降序
        var sortScoreStr = string.Empty;
        foreach (var item in orderQuery)
        {
          sortScoreStr += item + " ";
        }
        Console.WriteLine($"排序后的数据元素为:{sortScoreStr}");
    }

    序列升序或降序排序后结果如下5和6:

     

     

    2.5 group by

    group by子句用来对查询结果进行分组。如果结果分为两组,且未指定key的情况下,key取值默认是true和false。如果分为多组,获取数据结果时需要手动遍历key获取对应的value。示例如下:

    static void Main(string[] args)
    {
        var scores = new int[] { 56,97,98,57,74,86,31,90};
        var result = from score in scores group score by (score < 60);
        foreach (var item in result)
        {
            var str = $"{(item.Key ? "及格: " : "不及格: ")}";
            foreach (var it in item)
            {
                str += it + " ";
            }
            Console.WriteLine(str);
        }
    }

    运行结果为:

     

     对于查询结果分为多组的情况,根据key获取对应value的示例如下:

    static void Main(string[] args)
    {
        var numbers = new int[]{1,2,3,4,5,6,7,8,9};
        var numQuery = from num in numbers group num by (num%3);
        foreach (var numKey in numQuery)
        {
          var str = string.Empty;
          switch (numKey.Key)
          {
            case 0: str = $"整除3余数为0的元素有:{str}"; break;
            case 1:str = $"整除3余数为1的元素有:{str}"; break;
            case 2:str = $"整除3余数为2的元素有:{str}"; break;
          }
    
          foreach (var item in numKey)
          {
            str += item + " ";
          }
          Console.WriteLine(str);
        }
    }

    运行结果图:

     

    2.6 join

    join子句用于联合查询,一般会存在两个数据源,且两个数据源中有相同的字段可进行比较。使用格式为【join 数据 in 数据源1 on key1 equals key2】

    static void Main(string[] args)
    {
        var user1 = new User() {UserId = "1", UserName = "张三", UserPhone = "1234567997"};
        var user2 = new User() {UserId = "2", UserName = "李四", UserPhone = "18335789789"};
        var users = new List<User>() { user1, user2};
        var order1 = new Order {Id = "1", UserId = "1", OrderCode = "orderCode001"};
        var order2 = new Order {Id = "2", UserId = "1", OrderCode = "orderCode002"};
        var orders = new List<Order>{order1, order2};
        var joinQuery = from user in users
                join order in orders on user.UserId equals order.UserId
            select new
            {
              userId = user.UserId,
              userName = user.UserName,
              userPhone = user.UserPhone,
              orderCode = order.OrderCode,
            };
        foreach (var item in joinQuery)
        {
          Console.WriteLine(item);
        }
    }

    运行结果如下图8:

     

     

     

    3 linq方法查询

    linq查询中,为了更加清晰明了的阅读,我们一般采用查询语法,但有些查询操作没有等效的查询表达式,只能采用方法查询,即调用内部方法,有些场景中也可以将查询语法和方法语法结合使用。常见的方法又如下:

     

     示例:假设存在一个序列,scores = new int[] { 56,97,98,57,74,86,31,90},求最高分、最低分和平均分。

    static void Main(string[] args)
    {
        var queryInfo = from score in scores select score;
        var averqge = queryInfo.Average();
        var maxScore = queryInfo.Max();
        var minScore = queryInfo.Min();
        Console.WriteLine($"平均分为:{averqge}");
        Console.WriteLine($"最高分为:{maxScore}");
        Console.WriteLine($"最低分为:{minScore}");
    }

    运行结果如下图9:

     

     

    4 总结

    linq查询广泛应用在c#业务处理中,上述给出的示例,数据源均从对象结合中获取,对于从数据库获取的数据,采用db.XXXSet获取。对于集合中可能出现值为null的情况,查询时如果需要跳过null值,可设置筛选或查询字段为可空的(?表达式),对于查询的异常情况,我们可以使用try...catch捕获异常。

     

    5 参考

    《c#程序涉及教程》 李春葆,曾平,喻丹丹. 清华大学出版社。

    https://docs.microsoft.com/zh-cn/dotnet/csharp/linq/, 微软官网linq介绍。

  • 相关阅读:
    浅析数据库安全技术
    本站快捷付款方式
    VMware Workstation 官方正式版及激活密钥
    Win10真正好用之处
    我眼中的CentOS 下 安全策略
    美团
    Tomcat connector元素常用配置(最大连接数等)
    9.22面经:
    9.7
    合并两个有序数组为一个新的有序数组
  • 原文地址:https://www.cnblogs.com/mo-lu/p/13072289.html
Copyright © 2020-2023  润新知