你的位置:首页 > ASP.net教程

[ASP.net教程]分享一个递归无限级拼接Json的方法


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

 

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

下面是BaseService的方法

 

下面方法用于拼接字符串

主体方法--

 1 /// <summary> 2     /// 得到树TreePanel的Json 3     /// </summary> 4     /// <returns></returns> 5     public string GetAllLeftMenu4TreePanelJson() 6     { 7       StringBuilder allLeftMenuJsonStr = new StringBuilder(); 8       allLeftMenuJsonStr.Append("["); 9       int normal = Convert.ToInt32(Common.Enum.DelFlagEnum.Normal);//lambda表达式中不可以有类型转换10       List<AdminLeftMenuInfo> adminLeftMenuInfos = GetEntitesQueryable(m => m.DelFlag == normal).ToList();11       foreach (var adminLeftMenuInfo in adminLeftMenuInfos)12       {13         if (adminLeftMenuInfo.ParentId == 0)      //如果该元素的父ID为0  则是顶级元素14         {15           allLeftMenuJsonStr.Append("{");16           allLeftMenuJsonStr.Append("\"text\":\" " + adminLeftMenuInfo.PageName + " \" ");17           allLeftMenuJsonStr.Append(",");18 19           allLeftMenuJsonStr.Append("\"checked\":false");20           allLeftMenuJsonStr.Append(",");21           allLeftMenuJsonStr.Append("\"cls\":\"folder\"");22 23 24           List<AdminLeftMenuInfo> childrens = adminLeftMenuInfos.Where(m => m.ParentId == adminLeftMenuInfo.Id).ToList();25           if (childrens.Count != 0) //如果他还有儿子---拼接儿子26           {27             allLeftMenuJsonStr.Append(",");28             allLeftMenuJsonStr.Append("\"children\":");29             // var newChildrens=30             DoAppendChildJson4TreePanel(childrens, allLeftMenuJsonStr);31 32           }33 34           allLeftMenuJsonStr.Append("},");35 36         }37       }38       allLeftMenuJsonStr.Remove(allLeftMenuJsonStr.Length - 1, 1);39       allLeftMenuJsonStr.Append("]");40       return allLeftMenuJsonStr.ToString();41     }42     /// <summary>43     /// 用于全部TreePanel的递归子叶子的方法44     /// </summary>45     /// <param name="childrens">儿子作为参数</param>46     /// <param name="allLeftMenuJsonStr">把需要继续拼接的Json字符串传进来</param>47     private void DoAppendChildJson4TreePanel(List<AdminLeftMenuInfo> childrens, StringBuilder allLeftMenuJsonStr)48     {49       allLeftMenuJsonStr.Append("[");50       foreach (var children in childrens)51       {52         //判断children是否还有儿子,如果有为folder,如果没有儿子就是leaf,53         //并且checked=false;54         //  var son = GetEntitesQueryable(m => m.ParentId == children.Id);55         List<AdminLeftMenuInfo> son = GetEntitesQueryable(m => m.ParentId == children.Id).ToList();56         if (son.Count == 0) //没有儿子了 那么他就是叶子57         {58           allLeftMenuJsonStr.Append("{");59           allLeftMenuJsonStr.Append("\"text\":\"" + children.PageName + "\"");60           allLeftMenuJsonStr.Append(",");61           allLeftMenuJsonStr.Append("\"leaf\":true");62           allLeftMenuJsonStr.Append(",");63           allLeftMenuJsonStr.Append("\"checked\":false");64           allLeftMenuJsonStr.Append("},");65         }66         else//有儿子 那么他就是文件夹67         {68           allLeftMenuJsonStr.Append("{");69           allLeftMenuJsonStr.Append("\"text\":\"" + children.PageName + "\"");70           allLeftMenuJsonStr.Append(",");71           allLeftMenuJsonStr.Append("\"cls\":\"folder\"");72           allLeftMenuJsonStr.Append(",");73           allLeftMenuJsonStr.Append("\"checked\":false");74           allLeftMenuJsonStr.Append(",");75           allLeftMenuJsonStr.Append("\"children\":");76           DoAppendChildJson4TreePanel(son, allLeftMenuJsonStr);  //如果还有儿子 那么就一直递归下去77           allLeftMenuJsonStr.Append("},");78         }79 80       }81       allLeftMenuJsonStr.Remove(allLeftMenuJsonStr.Length - 1, 1);82       allLeftMenuJsonStr.Append("]");83     }

  

至于为什么我要把IQueryable转成List来操作,原因很简单:

Ef延迟加载,会在调用的时候,来执行代码,比如我们判断IQueryable<T>   t==null的时候  ,这时才会执行之前定义的查询动作。

如果此处一直操作Iqueryable,当我们第一次执行延迟加载动作查询数据库之后,第二次想使用同一个Iqueryable的时候,就会报错:

错误内容大概是SqlDataReader已经打开一个链接,请先将此链接关闭。错误是什么原因呢,就是第一次延迟加载后,连接并没有关闭,

在第二次调用集合离线查询的时候,代码会以为你还要重新执行查询,这时候是不允许的,所以为了离线操作,转换为了List集合,在内存中随便玩。

 

 

最后效果图奉上