Linq

Linq

1、查询表达式

  • 查询表达式是一种使用查询语法的表达式,它用于查询和转换来自任意支持Linq的数据源中的数据。

  • 查询表达式使用许多常见的c#语言构造,易读简介,容易掌握。

  • 它是由一组类似的sql或XQuery的声明性语法编写的字句组成。每个字句可以包含一个或多个C#表达式,这些表达式本身也可能是查询表达式或包含查询的表达式。

  • 查询表达式结构

    • 以from子句开头
    • 中间可以包括一个或多个where子句、let子句、join子句、orderby子句和group子句,甚至还可以是from子句。
    • 以select或者group子句结束
  • 各个字句介绍

    • from:制定查询操作的数据源和范围变量。

    • select:制定查询结果的类型和表现形式。

    • where:筛选元素的逻辑条件。

    • let:引入用来临时保存查询表达式中的子表达式结果的范围变量。

    • orderby:对查询结果进行排序操作,包括升序以及降序。

    • group :查询结果进行分组

    • into:提供一个临时标识符。join子句、group子句或者select子句可以通过该标识符引用查询操作中的中间结果。

    • join:链接多个用于查询操作的数据源 equals 以及on

      int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
      // 简单查询
      var arrQuery1 = from a in arr
                      select a;
      
      // 带条件的简单查询
      var arrQuery2 = from a in arr
                      where a < 5
                      select a;
      var arrNew = arrQuery1.ToArray<int>();
      
      // 关联查询
      int[] arr2 = new int[] { 11, 22, 33, 4, 45, 66, 87, 8, 90 };
      var arrQuery3 = from a in arr
                      from b in arr2
                      where a == b
                      select a;
      
      // 带计算的查询
      var arrQuery4 = from a in arr
                      select a * 10;
      
      // 查询后获取一个新对象
      var arrQuery5 = from a in arr
                      select new { // 匿名对象
                          id = a,
                          name = $"title-{a}"
                      };
      
      // 两个条件,不是用and或者or 而是用 && ||
      var arrQuery6 = from a in arr
                      where a >= 3 && a <= 6
                      select a;
      
      var arrQuery7 = from a in arr
                      where a >= 9 || a <= 3
                      select a;
      
      // 带函数的查询
      var arrQuery8 = from a in arr
                      where isEven(a)
                      select a;
      // 偶数判断
      static bool isEven(int a)
      {
          return a%2 == 0;
      }
      
      // let 子句  创建一个范围变量来存储结果
      var arrQuery9 = from a in arr
                      let b = a % 2 == 0
                      where b
                      select a;
      
      var arrQuery10 = from a in arr
                       let b = a % 2
                       where b == 0
                       select a;
      
      var arrQuery11 = from a in arr
                       let b = a % 2
                       select b;
      
      // orderby 子句,默认是升序ascending,降序用descending
      var arrQuery12 = from a in arr2
                       orderby a
                       select a;
      
      var arrQuery12 = from a in arr2
                       orderby a descending
                       select a;
      
      // 分组和排序
      var arrQuery13 = from a in arr
                       where a > 1 && a < 9
                       orderby a descending
                       group a by a % 2;
      foreach (var item in arrQuery13)
      {
          foreach (var num in item)
          {
              Console.WriteLine(num);
          }
          Console.WriteLine("-----分组-----");
      }
      
      // into 语法
      var arrQuery14 = from a in arr
                       where a > 1 && a < 9
                       orderby a descending
                       group a by a % 2 into g
                       from n in g // 临时标识符,存储数据
                       select n;
      foreach (var item in arrQuery14)
      {
          Console.WriteLine(item);
      }
      
      // join 用法  equals  效果等同于前面的arrQuery3
      var arrQuery15 = from a in arr
                       join b in arr2 on a equals b
                       select a;
      
      
      

2、Linq

Linq初级语法

// 复杂的分组与遍历
string[] strs = new string[] { "java", "C", "C++", "PASCAL", "FORTRAN", "LISP", "Prolog", "CLIPS", "OpenCyc", "Fazzy", "Python", "PHP", "Ruby", "Lua", "True basic", "Qbasic", "Virtual Basic" };
var arrQuery16 = from a in strs
                 group a by a.Length into g
                 orderby g.Key
                 select g;
foreach (var item in arrQuery16)
{
    foreach (var row in item)
    {
        Console.WriteLine($"{item.Key}={row}");
    }
}

ar arrQuery17 = from a in strs
                 group a by a.Length into g
                 orderby g.Key
                 select new
                 {
                     key = g.Key,
                     num = g.Count()
                 };
foreach (var item in arrQuery17)
{
    Console.WriteLine(item.ToString());    
}

协变与逆变

  • msdn解释:
    • 协变:能够使用与原始制定的派生类型相比,派生程度更大的类型。
    • 逆变:则指的是能够使用比派生程度更小的类型。
  • 协变(out:输出参数):很自然的变化,比如string →object
  • 逆变(in:输入参数):不正常的变化,比如object→string
  • 泛型参数标记为out,标明它是用来输出的,作为结果返回
  • 泛型参数标记为in,标明它是用来输入的,只能作为参数
class Animal
{
}
class Dog : Animal
{
}

Dog dog=new Dog();
Animal animal = dog; // 这种可以直接协变
List<Dog> dogs = new List<Dog> ();
List<Animal> animals = new List<Animal> ();
// animals = dogs; // 报错
animals = dogs.Select (dog =>  dog as Animal ).ToList ();

// 下面这种就可以,因为  public interface IEnumerable<out T> : IEnumerable
IEnumerable<Dog> someDogs = new List<Dog>();
IEnumerable<Animal> somAnimals = someDogs;

// 协变   public interface IEnumerable<out T> : IEnumerable
IEnumerable<Dog> someDogs = new List<Dog>();
IEnumerable<Animal> somAnimals = someDogs; // 强制转换为合法

// 逆变  public delegate void Action<in T>(T obj);
Action<Animal> animals = new Action<Animal>(a=>{ /* 动物叫的方法*/ });
Action<Dog> dogs = animals;
dogs(new Dog());

软件与数据间的问题

  • 任何软件都有代码和数据组成,任何开发都要与数据打交道
  • 在对象数据与数据库之间进行沟通经常会有一道坎
  • 是否能够简化程序与数据之间的沟通方式

Linq

  • Language Integrated Query 语言集成式查询
  • Linq将编程语言与数据的世界连接在一起
  • Linq实现了统一的数据访问方案

Linq构成

  • 查询运算符
  • 查询表达式
  • 表达式树
  • Linq的dll以及命名空间

查询运算符

image-20220908070407801

分类 分类
过滤 where、ofType 设置 Distinct 、except、Intersect 、Union
投射 select、selectMany 转换 AsEnumerable、AsQueryable、Cast、ToArray、ToList、ToDictionary
分段 Skip、SkipWhile、Take、TakeWhile 相等 SequenceEqual
排序 OrderBy、OrderByDescending、ThenBy、ThenByDescending、Reverse 元素 ElementAt、ElementAtOrDefault、First、FirstOrDefault、Last、LastOrDefault、Single、SingleOrDefault
拼接 Concat 生成 DefaultEmpty、Empty、Range、Repeat
联结 Join、GroupJoin 量词 All、Any、Contains
分组 GroupBy、ToLookup 聚合 Aggregate、Average、Count、LongCount、Max、Min、Sum
  • 过滤

    • Where - Where查询;延迟
    • OfType - 过滤集合中的指定类型;延迟
  • 设置

    • Distinct - 过滤集合中的相同项;延迟
    • Except - 从某集合中删除其与另一个集合中相同的项;延迟
    • Intersect - 获取不同集合的相同项(交集);延迟
    • Union - 连接不同集合,自动过滤相同项;延迟
  • 投射

    • Select - Select选择;延迟
    • selectMany- Select选择(一对多);延迟
  • 转换

    • Cast - 将集合转换为强类型集合;延迟
    • ToArray - 将集合转换为数组;不延迟
    • ToList - 将集合转换为List集合;不延迟
    • ToDictionary - 将集合转换为<K, V>集合;不延迟
  • 分组

    • Skip - 跳过集合的前n个元素;延迟
    • Take - 获取集合的前n个元素;延迟
    • SkipWhile - 直到某一条件成立就停止跳过;延迟
    • TakeWhile - 直到某一条件成立就停止获取;延迟
  • 相等

    • SequenceEqual - 判断两个集合是否相同;不延迟·
  • 排序

    • OrderBy - 按指定表达式对集合正序排序;延迟
    • ·OrderByDescending - 按指定表达式对集合倒序排序;延迟
    • ThenBy
    • ThenByDescending
    • Reverse - 对集合反向排序;延迟
  • 元素

    • ElementAt - 返回集合中指定索引的元素;不延迟
    • ElementAtOrDefault - 返回集合中指定索引的元素(如果没有则返回默认值);不延迟
    • First 返回集合中的第一个元素;不延迟
    • FirstOrDefault - 返回集合中的第一个元素(如果没有则返回默认值);不延迟
    • Last - 返回集合中的最后一个元素;不延迟
    • LastOrDefault- 返回集合中的最后一个元素(如果没有则返回默认值)
    • Single- 根据表达式返回集合中的某一元素;不延迟
    • SingleOrDefault - 根据表达式返回集合中的某一元素(如果没有则返回默认值);不延迟
  • 拼接

    • ·Concat - 连接不同集合,不会自动过滤相同项;延迟
  • 生成

    • DefaultEmpty - 查询结果为空则返回默认值;延迟
    • Empty
    • Range
    • epeat
  • 联结

    • Join - Join查询;延迟
    • GroupJoin - 分组Join查询;延迟
  • l量词

    • All- 判断集合中是否所有元素都满足某一条件;不延迟
    • Any - 判断集合中是否有元素满足某一条件;不延迟
    • Contains - 判断集合中是否包含有某一元素;不延迟
  • 分组

    • GroupBy- 分组;延迟
    • ToLookup
  • 聚合

    • Aggregate - 根据输入的表达式获取一个聚合值;不延迟
    • Average- 集合应为数字类型集合,求其平均值;不延迟
    • Count- 返回集合中的元素个数,返回int;不延迟
    • LongCount - 返回集合中的元素个数,返回long;不延迟
    • Max- 返回集合的最大值;不延迟
    • Min - 返回集合的最小值;不延迟
    • Sum - 集合应为数字类型集合,求其和;不延迟
posted @ 2022-09-17 17:09  his365  阅读(73)  评论(0编辑  收藏  举报