分享一个递归无限级拼接Json的方法---ExtJs的TreePanel和TreeGrid均适用(Ef,Lambda,Linq,IQueryable,List)

摘要:
//intnormal=转换.ToInt32(Common.Enum.DelFlagEnum.Normal);adminLeftMenuInfos=GetEntitesQueryable(m=>“”+adminLeftMenuInfo.DelFlag+“”);“任务文件夹”);真实”);

话不多说,先上实体类,如果你不是codefirst,就把它当成数据表结构。

分享一个递归无限级拼接Json的方法---ExtJs的TreePanel和TreeGrid均适用(Ef,Lambda,Linq,IQueryable,List)第1张

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

分享一个递归无限级拼接Json的方法---ExtJs的TreePanel和TreeGrid均适用(Ef,Lambda,Linq,IQueryable,List)第2张

下面是BaseService的方法

分享一个递归无限级拼接Json的方法---ExtJs的TreePanel和TreeGrid均适用(Ef,Lambda,Linq,IQueryable,List)第3张

下面方法用于拼接字符串

主体方法--

/// <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)第4张

免责声明:文章转载自《分享一个递归无限级拼接Json的方法---ExtJs的TreePanel和TreeGrid均适用(Ef,Lambda,Linq,IQueryable,List)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇pub/sub的实际应用总结Mysql----浅入浅出之视图、存储过程、触发器下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Element的表单验证规则,清空或填充数据如何避免自动触发

问题现象:表格校验,多选控件校验条件新建窗口,清空不起作用 考虑新建clearValidate方法 清空,没想到无效 通过查网上得到答案 使用nextTick方法,在弹框展示出来之前,JS执行完了所以没生效,此方法会在DOM更新后的回调中执行  this.dialogFormUser = true // 清除自动触发的表单验证 this....

vue $forceUpdate()强制刷新

改变列表的值 一直不渲染 <van-pull-refresh v-model="refreshing" @refresh="onRefresh"> <van-list v-model="loading" :finish...

HTML调用servlet(一)

1.页面的数据表单 在使用Servlet处理用户请求之前,先准备一个页面,该页面用来提供数据表单。数据表单就是HTML中的<form>...</form>部分,当用户单击Submit按钮提交表单之后,表单中包含的一些变量(或者成为字段)将会被发送到服务器端进行处理。下面编写一个HTML文件,文件代码如下: add.html &l...

vue项目动态新增表单、图片、文件

<div class="type_box" v-for="(item,index) in attrList" :key="item.id"> <div class="add-row"> <span class="label-span">key<...

kubernetes之健康状态检测

1.说明容器探针: kubelet 对容器执行的定期诊断探针执行方式: LivenessProbe: 判断容器是否存活 running状态, 如果不健康kubelet就会杀掉pod,根据重启策略RestartPolicy进行相应的处理 ReadinessProbe: 判断容器是否处于可用Ready状态, 达到ready状态表示pod可以接受请求, 如果...

微信内置浏览器清理缓存方法

目前感觉大部分所接触过的项目,目标用户几乎都是使用微信浏览器打开的,在一定程度来说,发布测试版还有本地测试的过程中,微信这种怎么也清不掉的缓存真的很烦人. 下面直入正题, 给出清除微信浏览器缓存的终极方法: 登出微信,再重新登录微信.  ☆☆☆ 如果嫌麻烦的话, 可以试一下不一定成功的清除缓存方法: 1. 重新刷新几次,直到缓存被刷掉   ☆ 2. 在改变...