做咩有D网站响网吧上不了/长沙网络营销公司排名
前言
树形结构是一种很常见的数据结构,类似于现实生活中的树的结构,具有根节点、父子关系和层级结构。
所谓根节点,就是整个树的起始节点。
节点则是树中的元素,每个节点可以有零个或多个子节点,节点按照层级排列,根节点属于第一层,其子节点属于第二层,以此类推,没有子节点的节点,则称为叶子,是最后一层。
父子关系就是节点之间的关系,每个节点都有父节点。
树形结构的应用非常广泛,例如在数据库中用来表示组织结构、目录结构,还用于实现树状菜单、文件系统等。
树形结构的灵活性和层次性使其成为处理具有层级关系数据的有力工具。
常见的树形结构包括二叉树、平衡树、B树等,它们在各个领域都有不同的应用场景和算法实现。
下面分享 EF6 查询并返回树形结构数据的 2 个思路和具体实现方法。
1. EF 生成数据表的实体类
/// <summary>
/// HTFP14 表实体类
/// </summary>
public partial class HTFP14
{public string COMPHT14 { get; set; }public string ACDEHT14 { get; set; }public string PGRPHT14 { get; set; }public string PKEYHT14 { get; set; }public string DESCHT14 { get; set; }public Nullable<decimal> PVALHT14 { get; set; }public string PSTRHT14 { get; set; }public string GLNOHT14 { get; set; }public string PCDEHT14 { get; set; }public string ATLVHT14 { get; set; }public string USERHT14 { get; set; }public System.DateTime LMDTMHT14 { get; set; }
}
2. 创建用于前端的 ViewModel 类
/// <summary>
/// 主菜单 UI 树形结构 ViewModel 类
/// </summary>
public class MainMenuViewModel
{[Description("菜单层次")]public int MenuLevel { get; set; }[Description("菜单码")]public string MenuCode { get; set; }[Description("菜单名称")]public string MenuName { get; set; }[Description("菜单对外显示名称")]public string MenuLabel{get{return $"{MenuCode} - {MenuName}";}}[Description("父菜单码")]public string ParentMenuCode { get; set; }[Description("菜单URL")]public string MenuUrl { get; set; }[Description("菜单授权用户")]public string MenuUser { get; set; }[Description("是否禁止")]public bool Disabled{get{if (string.IsNullOrEmpty(MenuUser)){return true;}return false;}}[Description("菜单排序")]public decimal MenuOrder { get; set; }[Description("子级菜单")]public IList<MainMenuViewModel> Children { get; set; }
}
3. 数据准备
-
获取初级菜单
/// <summary> /// 查询第一级菜单 /// </summary> /// <returns></returns> private IQueryable<MainMenuViewModel> GetFirstMenu() {var query = from t1 in _dbContext.HTFP14 where t1.PGRPHT14 == "MNGP" select new MainMenuViewModel{MenuCode = t1.PKEYHT14,MenuName = t1.DESCHT14,ParentMenuCode = "",MenuUrl = "",MenuUser = ""};return query; }
-
获取二级菜单
/// <summary> /// 查询第二级菜单 /// </summary> /// <param name="companyCode"></param> /// <returns></returns> private IQueryable<MainMenuViewModel> GetSecondMenu(string companyCode) {var query = from t1 in _dbContext.HTFP14where t1.PGRPHT14 == "MUGP" && t1.COMPHT14 == companyCodeselect new MainMenuViewModel{MenuCode = t1.PKEYHT14,MenuName = t1.DESCHT14,ParentMenuCode = t1.PCDEHT14,MenuUrl = "",MenuUser = ""};return query; }
-
获取三级(最终)菜单
/// <summary> /// 查询第三级(最终)菜单 /// </summary> /// <param name="companyCode"></param> /// <returns></returns> private IQueryable<MainMenuViewModel> GetThirdMenu(string menuUser, string companyCode) {var query = from t1 in _dbContext.HTFP02where t1.COMPHT02 == companyCode && t1.STSHT02 == "A"join t2 in (from t21 in _dbContext.HTFP03 where t21.USRMNHT03==menuUser && t21.COMPHT03==companyCode select t21) on t1.MNUCDHT02 equals t2.MNUCDHT03 into t1_t2from t12 in t1_t2.DefaultIfEmpty()select new MainMenuViewModel{MenuCode = t1.MNUCDHT02,MenuName = t1.DESCHT02,ParentMenuCode = t1.MNUGPHT02,MenuUrl = t1.URLHT02,MenuUser = t12.USRMNHT03};return query; }
-
解释:这样分开查询,简化代码,避免太复杂的 Linq 拼接
方法一
思路:使用 Linq 语法拼接查询,具体步骤如下:
-
在数据层用 Linq 拼接写查询方法
/// <summary> /// 查询主菜单树形结构数据 /// </summary> /// <param name="companyCode"></param> /// <returns></returns> public IQueryable<object> QueryMainMenus(string menuUser, string companyCode) {var query1 = GetFirstMenu();var query2 = GetSecondMenu(companyCode);var query3 = GetThirdMenu(menuUser, companyCode);var query = from t1 in query1select new{MenuCode = t1.MenuCode,MenuName = t1.MenuName,ParentMenuCode = t1.ParentMenuCode,MenuUrl = t1.MenuUrl,MenuUser = t1.MenuUser,Children = (from t2 in query2where t2.ParentMenuCode == t1.MenuCodeselect new{MenuCode = t2.MenuCode,MenuName = t2.MenuName,ParentMenuCode = t2.ParentMenuCode,MenuUrl = t2.MenuUrl,MenuUser = t2.MenuUser,Children = (from t3 in query3where t3.ParentMenuCode == t2.MenuCodeselect new{MenuCode = t3.MenuCode,MenuName = t3.MenuName,ParentMenuCode = t3.ParentMenuCode,MenuUrl = t3.MenuUrl,MenuUser = t3.MenuUser})})};return query; }
-
在业务层直接调用方法生成 List 返回给前端
-
总结
逻辑比较简单,有多个菜单可以一直添加下去,但代码会变得很长,所以比较适合事先知道层级并且层级数量不多的场景。
方法二(推荐)
思路:实体类 + 递归方法,具体步骤如下:
-
数据层 EF 使用 Union 方法返回整个树形结构数据:
/// <summary> /// 查询主菜单树形结构数据 /// </summary> /// <param name="companyCode"></param> /// <returns></returns> public IQueryable<MainMenuViewModel> QueryMainMenus(string menuUser, string companyCode) {var query1 = GetFirstMenu();var query2 = GetSecondMenu(companyCode);var query3 = GetThirdMenu(menuUser, companyCode);var query = query1.Union(query2).Union(query3);return query; }
-
业务层递归处理并返回集合数据给前端
public List<MainMenuViewModel> QueryMainMenus(string menuUser, string companyCode) {var list = hTFP02Reposition.QueryMainMenus(menuUser, companyCode).ToList();var list2 = GetData(list);return list2; }/// <summary> /// 处理树形结构数据 /// </summary> /// <param name="source"></param> /// <returns></returns> private List<MainMenuViewModel> GetData(List<MainMenuViewModel> source) {List<MainMenuViewModel> nodes = source.Where(x => x.ParentMenuCode == "").Select(x => x).ToList();foreach (MainMenuViewModel item in nodes){item.Children = GetChildren(source, item);}return nodes; }/// <summary> /// 递归处理树形结构数据 /// </summary> /// <param name="source"></param> /// <param name="node"></param> /// <returns></returns> private IList<MainMenuViewModel> GetChildren(List<MainMenuViewModel> source, MainMenuViewModel node) {IList<MainMenuViewModel> childrens = source.Where(c => c.ParentMenuCode == node.MenuCode).Select(x => x).ToList();foreach (MainMenuViewModel item in childrens){item.Children = GetChildren(source, item);}return childrens; }
-
总结
代码比较简单,但逻辑相对不如第一种方法好理解,递归方法的性能略逊于第一种方法,但可扩展性比较强,适用于无法事先知道层级数量的树形数据结构。
往期精彩
- 分享一个 .NET 通过监听器拦截 EF 消息写日志的详细例子
- 不会使用 EF Core 的 Code First 模式?来看看这篇文章,手把手地教你
- EF Core 性能很差?试试这 6 个小技巧
- 如何在 EF Core 中使用乐观并发控制
- EF Core 在实际开发中,如何分层?
我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊程序人生,共同学习,共同进步
相关文章:

分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
前言 树形结构是一种很常见的数据结构,类似于现实生活中的树的结构,具有根节点、父子关系和层级结构。 所谓根节点,就是整个树的起始节点。 节点则是树中的元素,每个节点可以有零个或多个子节点,节点按照层级排列&a…...

【柴油机故障诊断】基于斑马优化算法ZOA优化柴油机故障诊断附Matlab代码
% 柴油机故障诊断 - 基于斑马优化算法(Zebra Optimization Algorithm,ZOA)优化Transformer模型 % 代码示例仅为演示用途,实际应用中可能需要根据具体情况进行适当修改 % 初始化参数 maxIterations = 100; % 最大迭代次数 populationSize = 50; % 种群大小 % 斑马优化算法…...

C1W4.Assignment.Naive Machine Translation and LSH
理论课:C1W4.Machine Translation and Document Search 文章目录 1. The word embeddings data for English and French words1.1The dataThe subset of dataLoad two dictionaries 1.2 Generate embedding and transform matricesExercise 1: Translating English…...

智能听诊器:宠物健康监测的革新者
宠物健康护理领域迎来了一项激动人心的技术革新——智能听诊器。这款创新设备以其卓越的精确度和用户友好的操作,为宠物主人提供了一种全新的健康监测方法。 使用智能听诊器时,只需将其放置在宠物身上,它便能立即捕捉到宠物胸腔的微小振动。…...

001、Mac系统上Stable Diffusion WebUI环境搭建
一、目标 如标题所述,在苹果电脑(Mac)上搭建一套Stable Diffusion本地服务,以实现本地AI生图目的。 二、安装步骤 1、准备源码【等价于准备软件】 # 安装一系列工具库,包括cmake,protobuf,rust,python3.10,git,wge…...

k8s一些名词解释
潮汐计算 是一种根据负载变化动态调整资源分配的计算模式。其核心思想是利用峰值和非峰值时段的资源需求差异,动态地扩展或缩减计算资源。在 Kubernetes 环境中,可以通过自动扩展(auto-scaling)机制,根据工作负载的变化自动调整计算资源,最大化资源利用率并减少不必要的…...

ArkUI组件——循环控制/List
循环控制 class Item{name: stringprice:number}private items:Array<Item> [new Item("A0",2399),new Item("BE",1999),new Item("Ro",2799)] ForEach(this.items,(item:Item) > {})List组件 列表List是一种复杂的容器,…...

定制开发AI智能名片商城微信小程序在私域流量池构建中的应用与策略
摘要 在数字经济蓬勃发展的今天,私域流量已成为企业竞争的新战场。定制开发AI智能名片商城微信小程序,作为私域流量池构建的创新工具,正以其独特的优势助力企业实现用户资源的深度挖掘与高效转化。本文深入探讨了定制开发AI智能名片商城微信…...

网络安全(含面试题版)
一、网络概念 网络:一组相互连接的计算机,多台计算机组成,使用物理线路进行连接 作用: 数据交换 资源共享 二、网络分类 计算机网络覆盖的地理区域决定了它的类型。一般分为局域网(LAN)、城域网(MAN)、广域网(WAN)。 三、www万维网…...

牛客 7.13 月赛(留 C逆元 Ddp)
B-最少剩几个?_牛客小白月赛98 (nowcoder.com) 思路 奇数偶数 奇数;奇数*偶数 奇数 所以在既有奇数又有偶数时,两者结合可以同时删除 先分别统计奇数,偶数个数 若偶个数大于奇个数,答案是偶个数-奇个数 若奇个数…...

LeetCode 92. 反转链表 II
LeetCode 92. 反转链表 II 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 示例 1: 输入:head [1,2,3,4,5], left 2, right 4…...

mac M1 创建Mysql8.0容器
MySLQ8.0 拉取m1镜像 docker pull mysql:8.0创建挂载文件夹并且赋予权限 sudo chmod 777 /Users/zhao/software/dockerLocalData/mysql 创建容器并且挂载 docker run --name mysql_8 \-e MYSQL_ROOT_PASSWORDadmin \-v /Users/zhao/software/dockerLocalData/mysql/:/var/l…...

【Vue3】4个比较重要的设计模式!!
大家好,我是CodeQi! 一位热衷于技术分享的码仔。 在我投身于前端开发的职业生涯期间,曾有一次承接了一个大型项目的维护工作。此项目运用的是 Vue 框架,然而其代码结构紊乱不堪,可维护性极度糟糕😫。 这使我深刻领会到,理解并运用 Vue 中的重要设计模式是何等关键! …...

Ubuntu安装virtualbox(win10)
virtualbox下载安装 1、下载virtualbox 下载路径:Linux_Downloads – Oracle VM VirtualBox 根据自己的Ubuntu版本选择对应的安装包下载 2、安装virtualbox 到下载路径(一般为~/Download)打开终端输入命令 sudo dpkg -i xxx.deb 继续执…...

二次开发源码 借贷系统uniapp/借贷认证系统/小额信贷系统/工薪贷APP/资金贷系统h5
前端:UNIAPP 后端:ThinkPHP 数据库: Mysql 前端使用的uniapp 可以打包APP H5 小程序 系统提供了完善的网络借贷体系,为金融中介平台提供从获客到贷后管理全流程服务,解决了借贷手续繁琐、流程缓慢等问题 此源码为运营…...

LG 选择 Flutter 来增强其智能电视操作系统 webOS
可以这个话题会让大多数人困惑,2024 年了为什么还会冒出 webOS 这种老古董?然后 LG 为什么选择 webOS ?现在为什么又选择 Flutter ? 其实早在 Google I/O 发布 Flutter 3.22 版本的时候,就提到了 LG 选择 Flutter 来增…...

[ACM独立出版] 2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024,8月2日-4)
2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024)将于2024年8月2-4日在中国厦门召开。 VRISP 2024将围绕“虚拟现实、图像和信号处理”的最新研究领域,为来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、工程师等提供…...

ASP.NET Core中创建中间件的几种方式
前言 今天我们一起来盘点一下在ASP.NET Core应用程序中添加和创建中间件常见的四种方式。 中间件介绍 ASP.NET Core中间件(Middleware)是用于处理HTTP请求和响应的组件,它们被安排在请求处理管道中,并按顺序执行。中间件的设计是为…...

Atcoder ABC351 A-E 题解
A: 打卡题 题目描述 一中队和二中队正在进行一场棒球比赛,一中队是第一棒。 目前,比赛已进行到第九局上半,第九局下半即将开始。 一中队在 第i局 (1 < i < 9) 上半场得到了 Ai 分,二中队在 第j局 (1 < j < 8) 下…...

【终极指南】从零开始征服机器学习:初学者的黄金路线图
踏入机器学习的世界,对许多初学者而言,无疑是一场既兴奋又略带忐忑的冒险。尤其对于那些非数学或计算机专业背景的同学,或是已经在职场打拼的朋友们,寻找一条适合自己的入门路径,显得尤为重要。鉴于此,本文…...

MongoDB自学笔记(三)
一、前文回顾 上一篇文章中我们学习了更新操作,以及讲解了部分的更新操作符,今天我们继续学习剩余的更新操作符。 二、更新操作符 1、$rename 语法:{ $rename: { < field1 >: < newName1 >, < field2 >: < newName2…...

编程中的智慧之设计模式三
深入探索设计模式:实际应用和优化策略 在前两篇文章中,我们详细探讨了创建型模式、结构型模式、行为模式和架构模式的基本概念及其在Java中的实现。在本文中,我们将进一步探讨如何在实际项目中应用和优化这些模式,尤其是如何在大…...

《YOLOv10改进实战专栏》专栏介绍 专栏目录
《YOLOv10改进实战专栏》介绍及目录 YOLOv10官方仓库地址 专栏地址:点击跳转 专栏导航如下: 🎀基础入门篇🎀 万字长文,小白新手怎么开始做YOLO实验,从零开始教!整体思路在这里,科研指…...

Python酷库之旅-第三方库Pandas(030)
目录 一、用法精讲 79、pandas.Series.dtype属性 79-1、语法 79-2、参数 79-3、功能 79-4、返回值 79-5、说明 79-6、用法 79-6-1、数据准备 79-6-2、代码示例 79-6-3、结果输出 80、pandas.Series.shape属性 80-1、语法 80-2、参数 80-3、功能 80-4、返回值 …...

神经网络中的激活函数举例,它们各自的特点,以及哪个激活函数效果更好,为什么
sigmoid: \(\sigma(x)1/(1e^{-x})\); 优:将数值压缩到 0 1,导数为 \(\sigma(x)(1-\sigma(x))\) 好算。劣:输出均值非0(0.5),梯度消失(Gradient vanishing)每次…...

【树莓派3B+】控制引脚输出高低电平
前言一、安装RPI.GPIO库二、编写简单的输出高低电平的程序三、运行程序总结 前言 首先检查一下自己的板子有没有带库 我这个是有的。 ok,正式进入步骤 一、安装RPI.GPIO库 如果还没有安装RPi.GPIO库,可以通过以下命令在树莓派上安装: p…...

【Redis7】高阶篇
1 Redis单线程 VS 多线程(入门篇) 1.1 面试题 redis到底是单线程还是多线程? IO多路复用听说过吗? redis为什么快? 1.2 Redis为什么选择单线程? 1.2.1 是什么 这种问法其实并不严谨,为啥这么说呢? Redis的版本…...

在学习使用LabVIEW的过程中,需要注意哪些问题?
在学习使用LabVIEW的过程中,需要注意以下问题: 1. 基础知识 图形化编程思维: LabVIEW采用图形化编程方式,与传统的文本编程语言有很大不同,需要适应这种新的编程思维方式。数据流概念: 理解LabVIEW的核心数…...

网络编程-TCP/IP
网络概述 网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组合在一起。 每层实现不同的功能,其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务,同时使用下层提供的服务 网络体系结构…...

php在服务器上部署可视化运维工具详细列表
如果你的项目很小,可以用宝塔。但对于并发大的服务器管理,选择适合的工具非常重要。 目录 以下是一些免费且适合高并发管理的服务器管理工具推荐: 1Panel: Portainer: Webmin: Cockpit: …...