zoukankan      html  css  js  c++  java
  • 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介绍。

  • 相关阅读:
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(1)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建Viewport(2)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(2)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之完成登录功能
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之登录窗口调试
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建Viewport(1)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建输出验证码图片的控制器
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之调整首页显示
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之登录窗口
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(3)
  • 原文地址:https://www.cnblogs.com/mo-lu/p/13072289.html
Copyright © 2011-2022 走看看