C# 使用Queue高效检索树行数据符合条件的数据,并返回完整树形数据示例

最近有项目需要加载大型树数据,数据大概3W条

后端使用C# NET6 

前端使用Vue3 elementuiplus 虚拟tree =》解决大型树数据加载

遇到的问题是后端在检索数据时,要返回匹配数据的完整树目录

1.因为单条数据没有存放完整路径,需要通过父级ID逐级查找组装,导致性能急剧下降

2.数据包数据20M左右,前端下载受带宽影响也变慢

下面来说问题1

采用BOM树缓存,筛选时使用Queue来处理遍历数据加载符合条件的树数据如下

/// <summary>
        /// 过滤与重建树数据
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="predicate"></param>
        /// <param name="qualifiedNodes"></param>
        /// <returns></returns>
        public static List<BOM_DetailTree> FilterAndRebuildTreeOptimized(List<BOM_DetailTree> tree, Func<BOM_DetailTree, bool> predicate, HashSet<long> qualifiedNodes)
        {
            var result = new List<BOM_DetailTree>();
            // 使用队列来处理树的广度优先遍历
            var queue = new Queue<(BOM_DetailTree Node, List<BOM_DetailTree> Result)>();
            queue.Enqueue((tree.FirstOrDefault(n => n.ParentID == null || n.ParentID == 0), result));
            //while (stack.Count > 0)
             while (queue.Count > 0)
                {
                    var (currentNode, currentResult) = queue.Dequeue();

                // 如果当前节点满足条件或其子节点中有满足条件的,添加到结果树
                if (predicate(currentNode) || HasQualifiedChild(currentNode, predicate))
                {
                    var newNode = new BOM_DetailTree
                    {
                        Id = currentNode.Id,
                        ProjectCode = currentNode.ProjectCode,
                        MaterialCode = currentNode.MaterialCode,
                        MaterialName = currentNode.MaterialName,
                        ParentID = currentNode.ParentID,
                        ParentCode = currentNode.ParentCode,
                        MaterialCategory = currentNode.MaterialCategory,
                        QtyPerPiece = currentNode.QtyPerPiece,
                        UnAllotNum = currentNode.UnAllotNum,
                        ManualTotalQuantity = currentNode.ManualTotalQuantity,
                        IsPart = currentNode.IsPart,
                        IsStandard = currentNode.IsStandard,
                        PublishedStatus = currentNode.PublishedStatus,
                        IsUrgency = currentNode.IsUrgency,
                        NodeLevel = currentNode.NodeLevel,
                        IsSupplement = currentNode.IsSupplement,
                        AlterationStatusLable = currentNode.AlterationStatusLable,
                        IsShowTooltip = currentNode.IsShowTooltip,
                        IsAddBOM = currentNode.IsAddBOM,
                    };
                    currentResult.Add(newNode);

                    // 添加当前节点的子节点到栈中
                    if (currentNode.Children != null)
                    {
                        foreach (var child in currentNode.Children)
                        {
                           // stack.Push((child, newNode.Children ?? new List<BOM_DetailTree>()));
                            queue.Enqueue((child, newNode.Children ?? new List<BOM_DetailTree>()));
                        }
                    }
                }
            }

            return result;
        }


        /// <summary>
        /// 判断节点与子节点是否有匹配
        /// </summary>
        /// <param name="node"></param>
        /// <param name="filterPredicate"></param>
        /// <returns></returns>
        private static bool HasQualifiedChild(BOM_DetailTree node, Func<BOM_DetailTree, bool> filterPredicate)
        {
            if (filterPredicate(node))
            {
                return true;
            }

            if (node.Children != null)
            {
                foreach (var child in node.Children)
                {
                    if (HasQualifiedChild(child, filterPredicate))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
 

使用时

 Func<BOM_DetailTree, bool> filterPredicate = node =>
                node.PublishedStatus == 1;
                var qualifiedNodes = new HashSet<long>();
                var newTree= FilterAndRebuildTreeOptimized(cacheTree, filterPredicate, qualifiedNodes);

过滤效率毫秒级。

第二个问题

Startup添加响应数据压缩

 // 添加响应压缩服务
            services.AddResponseCompression(options =>
            {
                options.EnableForHttps = true;
                options.Providers.Add<GzipCompressionProvider>();
                options.Providers.Add<BrotliCompressionProvider>();
                options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                    new[] {  "application/json" });
            });

   app.UseResponseCompression();

优化后即时数据大的情况基本在2S以内响应结果,满足使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/621863.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ARM Cortex-M 系列 2.1 -- Cortex-M7 Debug system registers】

请阅读【嵌入式开发学习必备专栏】 文章目录 Debug system registers中断控制状态寄存器&#xff08;ICSR&#xff09;Debug Halting Control and Status Register, DHCSR Debug 寄存器DCRSR与DCRDRCPU 寄存器读操作CPU 寄存器写操作CPU 寄存器选择CPU 寄存器读写示例 调试故障…

Ubuntu安装VScode

Ubuntu安装VScode 前言&#xff1a; 1、Ubuntu安装VScode比较方便 2、我更喜欢source insight 1、获取到linux版本的VScode安装包 VSCode 下载地址是&#xff1a;https://code.visualstudio.com/ 2、得到安装包 3、复制到ubuntu中&#xff0c;使用命令安装 sudo dpkg -i cod…

安卓短视频一键搬运软件_V1.5.2 高级版

短视频一键搬运app是一款非常实用的视频处理软件&#xff0c;拥有各种各样的视频处理功能&#xff0c;可以帮助用户进行视频的多项处理&#xff0c;首先用户可以在这里为视频去除水印&#xff0c;打开视频文件过后&#xff0c;再把视频里面的水印内容框选出来&#xff0c;这样就…

第三课,python基础语法(二),基本算术运算符、3种数据类型、变量命名规则

一&#xff0c;基本算术运算 数学中&#xff1a;&#xff0c;-&#xff0c;&#xff0c; *小练习 请在程序中&#xff0c;定义如下变量&#xff1a; 钱包余额(变量名&#xff1a;money)&#xff0c;初始余额50 请通过程序计算&#xff0c;再购买了&#xff1a; 冰淇淋10元可…

【C语言/数据结构】栈:从概念到两种存储结构的实现

目录 一、栈的概念 二、栈的两种实现方式 1.顺序表实现栈 2.链表实现栈 三、栈的顺序存储结构及其实现 1.栈的声明 2.栈的初始化 3.栈的销毁 4.栈的压栈 5.栈的弹栈 6.栈的判空 7.返回栈顶元素 8.返回栈的长度 四、栈的链式存储结构及其实现 1.栈的声明 2.栈的…

[C++核心编程-03]----C++函数提高学习

目录 引言 正文 01-函数提升简介 02-函数默认参数 03-函数占位参数 04-函数重载 05-函数重载的注意事项 总结 引言 函数在C编程中扮演着至关重要的角色&#xff0c;通过合理使用函数&#xff0c;可以提高程序的结构性、灵活性、可读性和维护性。因此&…

汇昌联信:拼多多入驻条件是哪些?

在电商领域&#xff0c;拼多多以其独特的团购模式迅速崛起&#xff0c;吸引了众多商家的目光。想要在拼多多上开店&#xff0c;了解其入驻条件是必不可少的第一步。下面将详细解读拼多多的入驻条件&#xff0c;帮助有意加入的商家们做好准备。 一、企业资质要求 想要成功入驻拼…

STM32(GPIO)

GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 输入模式下可读取端口的高低电…

【C++】继承与多态的一些练习题

学习完了继承与多态&#xff0c;当然要来点练习题啦~ 第一题&#xff1a; class Base1 { public: int _b1; }; class Base2 { public: int _b2; }; class Derive : public Base1, public Base2 { public: int _d; }; int main(){ Derive d; Base1* p1 &d; Base2* p2…

Day_4

1. 地址簿功能 查询地址列表 属于常规方案 新增地址 属于常规方案 修改地址 删除地址 设置默认地址 2. 用户下单业务 数据库分析 订单表和订单明细表的关系&#xff1a;一对多 代码开发 controller 层 service 层 异常处理&#xff08;收货地址为空、超出配送范围、购物…

文件流-二进制文件(中北大学-程序设计基础(2))

目录 题目 源码 结果示例 题目 建立两个二进制磁盘文件f1.dat,f2.dat&#xff0c;编程实现以下工作&#xff1a; &#xff08;1&#xff09;将20个整数&#xff08;可在程序中初始化&#xff09;&#xff0c;分别存放到两个磁盘文件中&#xff0c;前10个放到f1.dat中&…

【数据可视化01】matplotlib实例介绍1

目录 一、引言二、实例介绍1.柱状图1)简单柱状图2)堆叠柱状图 2.线条形式3.折线图&#xff08;多子图&#xff09;4.散点图5.水平和垂直线条6.饼状图1&#xff09;饼状图2&#xff09;“条形饼”图 一、引言 matplotlib是一个用于绘制数据可视化的Python库。它可以创建各种静态…

Java并发编程:用户态、内核态、cache line和CPU缓存一致性协议

文章目录 一、介绍二、java中那些操作使用了内核态三、cache line的概念四、CPU缓存一致性协议 一、介绍 用户态和内核态是操作系统的两种运行状态&#xff0c;它们分别对应于不同的权限级别和访问能力。 用户态&#xff08;User Mode&#xff09;&#xff1a;这是应用程序运…

volatile详解、原理

文章目录 一、Volatile的定义和作用1.1 Volatile简介1.2 Volatile作用 二、并发编程中的三个问题&#xff1a;可见性、原子性、有序性二、Java内存模型&#xff08;JMM&#xff09;三、volatile变量的特性3.1 线程可见性3.2 禁止重排序禁止重排序原理禁止重排序举例 3.3 volati…

知乎知+广告推广该如何做?怎么收费?

知乎作为一个汇聚高质量用户群体的知识分享平台&#xff0c;成为了众多品牌和产品推广的优选之地。特别是知乎的“知”广告推广服务&#xff0c;以其精准定向、内容原生的特点&#xff0c;深受广告主青睐。 一、知乎知广告推广基础 1. 什么是知乎知&#xff1f; 知是知乎官方…

Java入门基础学习笔记11——关键字和标识符

1、关键字 关键字是java中已经被赋予特定意义的&#xff0c;有特殊作用的一些单词&#xff0c;不可以把这些单词作为标识符来使用。 注意&#xff1a;关键字是java用了的&#xff0c;我们就不能用来作为&#xff1a;类名、变量名、否则会报错。 标识符&#xff1a; 标识符就是…

RAG应用中的路由模式

依据的用户查询意图在 RAG 应用程序使用“路由控制模式”可以帮助我们创建更强大的 RAG 应用程序。我们通常希望用户能够访问的数据可以来自各种来源,如报告、文档、图片、数据库和第三方系统。 对于基于业务的 RAG 应用程序,我们可能还希望用户能够与其它业务系统进行交互,…

Linux 中 alarm 函数详解

目录 简介函数原型函数参数返回值使用示例设置 3 秒闹钟修改闹钟与取消闹钟设置 1 秒周期定时器 更多内容 简介 alarm 函数的功能是设置一个闹钟&#xff08;定时器&#xff09;&#xff0c;当闹钟时间到时&#xff0c;内核会向当前进程发送一个 SIGALRM 信号。 打开 Linux 终…

汇昌联信电商:拼多多新手怎么做店铺的免费流量会慢慢起来?

在拼多多上开店&#xff0c;新手们往往面临着如何吸引免费流量的挑战。毕竟&#xff0c;流量是店铺生存和发展的血脉&#xff0c;没有流量&#xff0c;就没有销量&#xff0c;店铺也就失去了生命力。那么&#xff0c;作为拼多多新手&#xff0c;如何做才能让店铺的免费流量慢慢…

Python Socket

一、服务端 from socket import *def print_hi(name):print(fHi, {name})# 允许所有ip连接IP 0.0.0.0# 端口PORT 8003# 定义一次从socket缓冲区读入512个字节数据BUFFER_LEN 512# 实例化socket对象 listenSocket 用来监听的socketlistenSocket socket(AF_INET, SOCK_STREA…