分享一个递归无限级拼接Json的方法---ExtJs的TreePanel和TreeGrid均适用(Ef,Lambda,Linq,IQueryable,List)
话不多说,先上实体类,如果你不是codefirst,就把它当成数据表结构。

下面是底层BaseDal获取数据的方法 (如果你没有Base类,直接写在你的DAL层和BLL层)

下面是BaseService的方法

下面方法用于拼接字符串
主体方法--
/// <summary>
/// 得到****TreeGrid****的Json ,后台用于管理页面
/// </summary>
public string GetAllLeftMenu4TreeGridJson()
{
StringBuilder allLeftMenuJsonStr = new StringBuilder();
allLeftMenuJsonStr.Append("["); //int normal = Convert.ToInt32(Common.Enum.DelFlagEnum.Normal);//lambda表达式中不可以有类型转换
//List<AdminLeftMenuInfo> adminLeftMenuInfos = GetEntitesQueryable(m => m.DelFlag == normal).ToList();
List<AdminLeftMenuInfo> adminLeftMenuInfos = GetEntitesQueryable(m => m.DelFlag != -1).ToList(); //这样就是查询所有 软删除的也查询,未删除的也查询,便于前台进行管理 foreach (var adminLeftMenuInfo in adminLeftMenuInfos)
{
if (adminLeftMenuInfo.ParentId == 0) //如果该元素的父ID为0 则是顶级元素
{
allLeftMenuJsonStr.Append("{");
allLeftMenuJsonStr.Append("\"text\":\" " + adminLeftMenuInfo.PageName + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"url\":\" " + adminLeftMenuInfo.PageUrl + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"delFlag\":\" " + adminLeftMenuInfo.DelFlag + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"Id\":\" " + adminLeftMenuInfo.Id + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"iconCls\":\"task-folder\"");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"expanded\":true"); List<AdminLeftMenuInfo> childrens = adminLeftMenuInfos.Where(m => m.ParentId == adminLeftMenuInfo.Id).ToList();
if (childrens.Count != 0) //如果他还有儿子---拼接儿子
{
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"children\":");
DoAppendChildJson4TreeGrid(childrens, allLeftMenuJsonStr, adminLeftMenuInfos); } allLeftMenuJsonStr.Append("},"); }
}
allLeftMenuJsonStr.Remove(allLeftMenuJsonStr.Length - 1, 1);
allLeftMenuJsonStr.Append("]");
return allLeftMenuJsonStr.ToString();
} private void DoAppendChildJson4TreeGrid(List<AdminLeftMenuInfo> childrens, StringBuilder allLeftMenuJsonStr, List<AdminLeftMenuInfo> adminLeftMenuInfos)
{
allLeftMenuJsonStr.Append("[");
foreach (var children in childrens)
{
//判断children是否还有儿子,如果有为folder,如果没有儿子就是leaf,
//并且checked=false;
// var son = GetEntitesQueryable(m => m.ParentId == children.Id);
List<AdminLeftMenuInfo> son = adminLeftMenuInfos.Where(m => m.ParentId == children.Id).ToList();
if (son.Count == 0) //没有儿子了 那么他就是叶子
{
allLeftMenuJsonStr.Append("{");
allLeftMenuJsonStr.Append("\"text\":\"" + children.PageName + "\"");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"leaf\":true");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"delFlag\":\" " + children.DelFlag + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"iconCls\":\"task\"");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"Id\":\" " + children.Id + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"url\":\" " + children.PageUrl + " \" ");
allLeftMenuJsonStr.Append("},");
}
else//有儿子 那么他就是文件夹
{
allLeftMenuJsonStr.Append("{");
allLeftMenuJsonStr.Append("\"text\":\"" + children.PageName + "\"");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"iconCls\":\"task-folder\"");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"expanded\":true");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"url\":\" " + children.PageUrl + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"delFlag\":\" " + children.DelFlag + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"Id\":\" " + children.Id + " \" ");
allLeftMenuJsonStr.Append(",");
allLeftMenuJsonStr.Append("\"children\":");
DoAppendChildJson4TreeGrid(son, allLeftMenuJsonStr,adminLeftMenuInfos);
allLeftMenuJsonStr.Append("},");
} }
allLeftMenuJsonStr.Remove(allLeftMenuJsonStr.Length - 1, 1);
allLeftMenuJsonStr.Append("]");
}
至于为什么我要把IQueryable转成List来操作,原因很简单:
Ef延迟加载,会在调用的时候,来执行代码,比如我们判断IQueryable<T> t==null的时候 ,这时才会执行之前定义的查询动作。
如果此处一直操作Iqueryable,当我们第一次执行延迟加载动作查询数据库之后,第二次想使用同一个Iqueryable的时候,就会报错:
错误内容大概是SqlDataReader已经打开一个链接,请先将此链接关闭。错误是什么原因呢,就是第一次延迟加载后,连接并没有关闭,
在第二次调用集合离线查询的时候,代码会以为你还要重新执行查询,这时候是不允许的,所以为了离线操作,转换为了List集合,在内存中随便玩。
优化描述:整个过程中只有一次查询数据库,这就是linq的筛选好处所在。每次进入递归的时候,都会把我们第一个主体方法查出来的List集合作为参数
传递进去。这样一来,避免了递归方法中查询,递归中的查询是很影响效率的。
最后效果图奉上

分享一个递归无限级拼接Json的方法---ExtJs的TreePanel和TreeGrid均适用(Ef,Lambda,Linq,IQueryable,List)的更多相关文章
- 分享一个关于jackson的Json工具类
直接贴代码: import org.codehaus.jackson.map.DeserializationConfig.Feature; import org.codehaus.jackson.ma ...
- 分享一个 pycharm 专业版的永久使用方法
刚开始接触Python,首先要解决的就是Python开发环境的搭建. 目前比较好用的Python开发工具是PyCharm,他有社区办和专业版两个版本,但是社区版支持有限,我们既然想好好学python, ...
- .NET ->> 分享一个字符串模糊匹配指数的方法
链接: http://www.tsjensen.com/blog/post/2011/05/27/Four+Functions+For+Finding+Fuzzy+String+Matches+In+ ...
- 分享一个js加密的几种方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [C#]一个简易的、轻量级的方法并行执行线程辅助类
一个简易的.轻量级的方法并行执行线程辅助类 在实际应用中,经常要让多个方法并行执行以节约运行时间,线程就是必不可少的了,而多线程的管理经常又是一件头疼的事情,比如方法并行执行异步的返回问题,方法并 ...
- python判断字符串是否是json格式方法分享
python判断字符串是否是json格式方法分享 在实际工作中,有时候需要对判断字符串是否为合法的json格式 解决方法使用json.loads,这样更加符合'Pythonic'写法 代码示例: ...
- 分享一个解决MySQL写入中文乱码的方法
分享一个解决MySQL写入中文乱码的方法 之前有发帖请教过如何解决MySQL写入中文乱码的问题.但没人会,或者是会的人不想回答.搜索网上的答案并尝试很多次无效,所以当时就因为这个乱码问题搁浅了一个软件 ...
- c#输出json,其中包含子json (可以含 无限级 子json)的方法思路
首页 给出 DataTable 转Json 的方法: public static string TableToJson(DataTable dt) { List<Dictionary<s ...
- 分享一个解析XML成为php数组的方法
原文:分享一个解析XML成为php数组的方法 <?php /* * To change this template, choose Tools | Templates * and open th ...
随机推荐
- Unity 热更新实例一、C#Light 和UI系统使用实例
接下来我会运用热更新的机制,逐步制作一些例子来阐释脚本系统如何和Unity结合. 脚本不限于使用C#Lite,但是C#Lite会有一些便利之处,请往下看. 结合机制也不限于这一种,但是C#Lite的设 ...
- 创业6&7
周末两天泡咖啡店. 起不来,只好下午去. 周六5点到9点. 周日3点到12点. 1)整理直播课程讲义.完成50%. 2)修改GMTC演讲稿.完成. 招行的单子还是拒了,目前还没准备好高可用的App服务 ...
- IOS 多线程04-GCD详解 底层并发 API
注:本人是翻译过来,并且加上本人的一点见解. 前言 想要揭示出表面之下深层次的一些可利用的方面.这些底层的 API 提供了大量的灵活性,随之而来的是大量的复杂度和更多的责任.在我们的文章常见的后台实践 ...
- Flex contextMenu
没想到再这里也要跌跌撞撞. 这个东西我很久之前就懂了的啊! 最开始是这么写的: private function init():void { var contextMenu:ContextMenu = ...
- 爱上MVC~一个Action多套View模版的设计
回到目录 模块化 这个问题是在做模块化设计时出现的,在Lind.DDD.Plugins模块里,需要对应的模块实体,模块管理者,模块标识接口等,开发时,如果你的功能点属于一个模块,需要实现IPlugin ...
- fir.im Weekly - Stanford 的 Swift 课程来了
上周提过,Swift 的 Github 主页上已经有了 >>「Port to Android」,这周重点推荐一下 Stanford 的 Swift 课程. Developing iOS 9 ...
- DateUtil
//有些地方需要修改 import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDate ...
- jeasyUI的treegrid批量删除多行(转载)
看上去,JavaScript的变量类型,也可以分为值类型和引用类型.赋值操作中,值类型,各自独立,互不干涉:引用类型,指针而已,大家指向同一个对象. 为什么这样说呢? 我是从jeasyUI的treeg ...
- Linux快速入门02-文件系统管理
继续进入Linux文件系统的学习,加油,早日突破MS压在自己身上的那道束缚. Linux系列文章 快速入门系列--Linux--01基础概念 快速入门系列--Linux--02文件系统管理 快速入门系 ...
- js对象、数组转换字符串
对象转换成字符串需要使用toString()方法. 1 var a = function(){ 2 console.log(111); 3 }; 4 var b = a.toString(); 5 c ...