【.NET Core】Linq查询运算符(三)

news/2024/5/20 0:07:57 标签: .netcore, linq, 数据库, c#, asp.net, .net, 开发语言

【.NET Core】Linq查询运算符(三)

文章目录

  • 【.NET Core】Linq查询运算符(三)
    • 一、概述
    • 二、串联运算
      • 2.1 Enumerable.Concat
    • 三、聚合运算
      • 3.1 Aggregate
      • 3.2 Average
      • 3.3 Count
      • 3.4 LongCount
      • 3.5 Max 或 MaxBy
      • 3.6 Min 或 MinBy
      • 3.7 Sum
    • 四、聚合运算
      • 4.1 Join
      • 4.1 GroupJoin
    • 五、数据分组
      • 5.1 GroupBy
      • 5.2 ToLookup
    • 六、总结

一、概述

查询运算符是组成Linq模式的方法。这些方法中的大多数都作用于序列;其中序列指其类型实现IEnumberable<T>接口或IQueryable<T>接口的对象。标准查询运算符提供包括筛选、投影、集合、排序等查询功能。

查询运算符包含两组,一组作用于类型IEnumberable<T>的对象,另一组作用于类型IQueryable<T>的对象。

《Linq查询运算符(一)》详细介绍了筛选数据投影运算设置运算数据排序限定符运算数据分区

《Linq查询运算符(二)》详细介绍了生成运算相等运算元素运算转换数据类型等,

本文将继续介绍Linq运算符串联运算聚合运算联接运算数据分组

二、串联运算

2.1 Enumerable.Concat

连接两个序列。

c#">public static System.Collections.Generic.IEnumerable<TSource> Concat<TSource> (this System.Collections.Generic.IEnumerable<TSource> first, System.Collections.Generic.IEnumerable<TSource> second);

参数类型

TSource:输入序列中的元素的类型。

参数

first IEnumerable

要连接的第一个序列

second IEnumerable

要与第一个序列连接的序列

返回

一个包含两个输入序列的连接元素的IEnumerable

c#">Person[] parameters = new Person[]
{
   new Person() { Id = 1, Code = "052", Name = "正一郎" },
   new Person() { Id = 2, Code = "028", Name = "正贰郎" },
   new Person() { Id = 3, Code = "020", Name = "正叁郎" }
};
Person[] parameters1 = new Person[]{
   new Person() { Id = 1, Code = "030", Name = "次一郎" },
   new Person() { Id = 2, Code = "031", Name = "次二郎" },
   new Person() { Id = 3, Code = "032", Name = "次三郎" }
};
var three= parameters.Select(p => p.Name).Concat(parameters1.Select(p=>p.Name));
foreach (var person in three) 
{
   Console.WriteLine(person);
}

输出结果

正一郎
正次郎
誠三郎
次一郎
次贰郎
次叁郎

三、聚合运算

聚合运算从值的集合中计算出单个值。

3.1 Aggregate

对序列应用累加器函数。 将指定的种子值用作累加器的初始值,并使用指定的函数选择结果值。

c#">public static TResult Aggregate<TSource,TAccumulate,TResult> (this System.Linq.IQueryable<TSource> source, TAccumulate seed, System.Linq.Expressions.Expression<Func<TAccumulate,TSource,TAccumulate>> func, System.Linq.Expressions.Expression<Func<TAccumulate,TResult>> selector);

类型参数

TSource source的元素类型。

TAccumulate 累加器值的类型。

TResult 结果值的类型。

参数

source 要对其进行聚合的序列

seed TAccumulate累加器的初始值

func Expression<Func<TAccumulate,TSource,TAccumulate>>

要对每个元素调用的累加器函数

selector Expression<Func<TAccumulate,TResult>>

将累加器的最终值转换为结果值的函数。

返回

TResult

已转换的累加器最终值。

c#">string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
string result=  fruits.AsEnumerable().Aggregate("", (current, next) => current + " " + next+"   ");
Console.WriteLine(result);

运行结果

apple    mango    orange    passionfruit    grape

3.2 Average

计算可以为 null 的数值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

定义

public static T Average (this System.Collections.Generic.IEnumerable<T> source);

T为数值类型

string[] numbers = { "100", "98", "50","2" };
double average = numbers.Average(num => long.Parse(num));
Console.WriteLine("The average is {0}.", average);

运行结果

The average is 62.5.

3.3 Count

返回指定的序列中满足条件的元素数量。

定义

public static int Count<TSource> (this System.Collections.Generic.IEnumerable<TSource> source);
c#">string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
int fruitCount = fruits.Count();
Console.WriteLine($"水果的种类:{fruitCount}.");
int fruitCount2 = fruits.Count(e=>e.IndexOf('m')==0);
Console.WriteLine($"水果的种类:{fruitCount2}.");

运行结果

水果的种类:5.
水果的种类:1.

3.4 LongCount

返回序列中的元素数量的Int64

定义

c#">public static long LongCount<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,bool> predicate);
c#">string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
long fruitCount = fruits.LongCount();
Console.WriteLine($"水果的种类:{fruitCount}.");
long fruitCount2 = fruits.LongCount(e=>e.IndexOf('m')==0);
Console.WriteLine($"水果的种类:{fruitCount2}.");

运行结果

水果的种类:5.
水果的种类:1.

3.5 Max 或 MaxBy

确定集合中的最大值

定义

c#">public static TSource? Max<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, System.Collections.Generic.IComparer<TSource>? comparer);
c#">string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
string[] numbers = { "100", "98", "50","2" };
int maxInt = numbers.Max(x => int.Parse(x));
Console.WriteLine(maxInt);
int maxLength = fruits.Max(x => x.Length);
Console.WriteLine(maxLength);

运行结果

100
12

3.6 Min 或 MinBy

确定集合中的最下值

c#">Min<TSource>(IEnumerable<TSource>, Func<TSource,Double>)
c#">string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
string[] numbers = { "100", "98", "50","2" };
int minInt = numbers.Min(x => int.Parse(x));
Console.WriteLine(minInt);
int minLength = fruits.Min(x => x.Length);
Console.WriteLine(minLength);

运行结果

2
5

3.7 Sum

对集合中的值求和。如果 source 不包含任何元素,则此方法返回零。

定义

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

四、聚合运算

联接两个数据源就是将一个数据源中的对象与另一个数据源中具有相同公共属性的对象相关联。

当查询所有面向的数据源相互之间具有无法直接领会的关系时,Join就成为一项重要的运算。在面向对象的编程中,这可能意味着建模对象之间进行关联。Linq框架中提供的join方法包括Join和GroupJoin。这些方法执行同等联接。既根据2个数据源的键是否相等来匹配这2个数据源的联接。

定义测试测试类Product

c#">class Product
{
    public string? Name { get; set; }
    public int CategoryId { get; set; }
}

定义测试测试类Category

c#">class Category
{
    public int Id { get; set; }
    public string? CategoryName { get; set; }
}

4.1 Join

根据键选择器函数Join两个序列并提取值对。

表达式语法

Join … in … on … equals …

c#">List<Product> products = new List<Product>
{
     new Product { Name = "Cola", CategoryId = 0 },
     new Product { Name = "Tea", CategoryId = 0 },
     new Product { Name = "Apple", CategoryId = 1 },
     new Product { Name = "Kiwi", CategoryId = 1 },
     new Product { Name = "Carrot", CategoryId = 2 } 
};
List<Category> categories = new List<Category> {
     new Category { Id = 0, CategoryName = "Beverage" },
     new Category { Id = 1, CategoryName = "Fruit" },
     new Category { Id = 2, CategoryName = "Vegetable" }
};
var query = from product in products
            join category in categories on product.CategoryId equals category.Id
            select new { product.Name,product.CategoryId, category.CategoryName };
foreach (var item in query)
{
     Console.WriteLine($"{item.Name} - {item.CategoryName}");
}

运行结果

Cola - Beverage
Tea - Beverage
Apple - Fruit
Kiwi - Fruit
Carrot - Vegetable

4.1 GroupJoin

根据键选择器函数Join两个序列,并对每个元素的结果匹配项进行分组。

表达式语法

join … in … on … equals …

c#">List<Product> products = new List<Product>
{
       new Product { Name = "Cola", CategoryId = 0 },
       new Product { Name = "Tea", CategoryId = 0 },
       new Product { Name = "Apple", CategoryId = 1 },
       new Product { Name = "Kiwi", CategoryId = 1 },
       new Product { Name = "Carrot", CategoryId = 2 } 
};
List<Category> categories = new List<Category> {
     new Category { Id = 0, CategoryName = "Beverage" },
     new Category { Id = 1, CategoryName = "Fruit" },
     new Category { Id = 2, CategoryName = "Vegetable" }
};

var productGroups = from category in categories
                    join product in products on category.Id equals product.CategoryId
                    into productGroup select productGroup;
foreach (IEnumerable<Product> productGroup in productGroups)
{
    Console.WriteLine("Group");
    foreach (Product product in productGroup)
    {
       Console.WriteLine($"{product.Name,8}");
    }
}

五、数据分组

分组是指将数据分到不同的组,使每组中的元素拥有公共的属性。

5.1 GroupBy

对共享通用属性的元素进行分组,每组由一个IGrouping<TKey,TElement>对象表示

查询表达式语法

groupby

c#">List<Product> products = new List<Product>
{
       new Product { Name = "Cola", CategoryId = 0 },
       new Product { Name = "Tea", CategoryId = 0 },
       new Product { Name = "Apple", CategoryId = 1 },
       new Product { Name = "Kiwi", CategoryId = 1 },
       new Product { Name = "Carrot", CategoryId = 2 } 
};
List<Category> categories = new List<Category> {
     new Category { Id = 0, CategoryName = "Beverage" },
     new Category { Id = 1, CategoryName = "Fruit" },
     new Category { Id = 2, CategoryName = "Vegetable" }
};

var proGroups = products.GroupBy(e => e.CategoryId);
foreach (var gp in proGroups)
{
     Console.WriteLine($"GroupByValue:{gp.Key}");
     foreach (var g in gp)
     {
         Console.WriteLine($"GroupValue:{g.Name}");
     }
}

Console.WriteLine($"=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=");
var goups = from product in products group product by product.CategoryId into productGroup select productGroup;
foreach (var ps in goups) 
{
   Console.WriteLine($"GroupByKey:{ps.Key}");
   foreach (var grp in ps) 
   {
       Console.WriteLine($"GroupValue:{grp.Name}");
   }
}

5.2 ToLookup

根据指定的键选择器和元素选择器函数,从IEnumerable生成一个泛型Lookup<TKey,TElement>。

语法:

c#">public static System.Linq.ILookup<TKey,TElement> ToLookup<TSource,TKey,TElement> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,TKey> keySelector, Func<TSource,TElement> elementSelector);

类型参数

TSource source的元素类型。

TKey keySelector返回的键的类型。

TElement elementSelector返回的值的类型。

ILookup<int, string> lookupProduct = products .ToLookup(p => p.CategoryId,p => p.Name);
foreach (var vproduct in lookupProduct) 
{
     Console.WriteLine($"Key:{vproduct.Key}");
     foreach (var pro in vproduct) 
     {
          Console.WriteLine($"Value:{pro}");
      }
}

六、总结

LINQ采用表达式声明性的查询语法编写,这样可以用最少的代码进行对数据结构操作。Linq也提供丰富的操作函数,在实际的使用中根据不同应用常见选择恰当的方法。


http://www.niftyadmin.cn/n/5270669.html

相关文章

golang os 包用法

Go语言的os包提供了许多用于与操作系统交互的功能。这个包涵盖了文件操作、环境变量、进程等许多方面。以下是一些os包的基本用法&#xff1a; 文件操作 创建文件 file, err : os.Create("filename.txt") if err ! nil {// 处理错误 } defer file.Close()打开文件…

【C语言】实战项目——通讯录

引言 学会创建一个通讯录&#xff0c;对过往知识进行加深和巩固。 文章很长&#xff0c;要耐心学完哦&#xff01; ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 引言 实战 建…

【数据结构—队列的实现】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、队列 1.1队列的概念及结构 二、队列的实现 2.1头文件的实现—Queue.h 2.2源文件的实现—Queue.c 2.3源文件的测试—test.c 三、测试队列实际数据的展示 3.…

计算机网络:数据链路层(VLAN)

今天又学到一个知识&#xff0c;加油&#xff01; 目录 一、传统局域网的局限&#xff08;促进VLAN的诞生&#xff09; 二、VLAN简介 三、VLAN的实现 总结 一、传统局域网的局限&#xff08;促进VLAN的诞生&#xff09; 缺乏流量隔离:即使把组流量局域化道一个单一交换机中…

python通过selenium获取输入框的文本值爬取编辑框内容

以百度首页的输入框为例,当输入‘你好‘后&#xff0c;html中的value的值会变成‘你好’ from selenium import webdriver web webdriver.Chrome() web.get(http://www.baidu.com) # 初始页面 cc web.find_element_by_xpath(//*[id"kw"]) #定位输入通过复制xpat…

chrome升级后,调试vue在控制台输出总是显示cjs.js

当前chrome版本120.0.6099.72 在vue中使用console.log输出时&#xff0c;总是显示cjs.js多少多少行&#xff0c;不能显示源文件名及行数 【解决方案】 打开控制台的设置 左侧找到“Ignore List”&#xff0c;取消勾选"enable Lgnore Listing"&#xff0c;并重启chr…

HttpRunner接口自动化测试框架

简介 HttpRunner是一款面向 HTTP(S) 协议的通用测试框架&#xff0c;只需编写维护一份 YAML/JSON 脚本&#xff0c;即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。 项目地址&#xff1a;GitHub - httprunner/httprunner: HttpRunner 是一个开源的 API/UI…