这个一个遍历树的循环,能完成任务,可是我不明白原理。比如 表中有3条数据 
Id    ParentId
1        0
2        1
3        1
当循环到第二条 Id为2的时候,此时并没有对应的ParentId
所以dr.Length不满足条件,我感觉应该不会在循环了,
此时断点跳到最后一行,我在按一下 觉得应该跳到16行 return了,
可是跳到了倒数第二行,然后又执行for循环,在依次执行剩下的任务,直到结束……我不明白为什么会这样,请大虾通俗的讲解一下,谢谢了。        public DataTable GetList(int PId)
        {
            StringBuilder strSql = new StringBuilder();
            strSql.Append("select Id,Title,ParentId,ClassList,ClassLayer,SortId,PageUrl,KindId from dt_Channel");
            DataSet ds = DbHelperOleDb.Query(strSql.ToString());
            DataTable oldData = ds.Tables[0] as DataTable;
            if (oldData == null)
            {
                return null;
            }            //复制结构
            DataTable newData = oldData.Clone();
            //组合成DAGATABLE
            GetChannelChild(oldData, newData, PId);
            return newData;
        }        private void GetChannelChild(DataTable oldData, DataTable newData, int PId)
        {
            DataRow[] dr = oldData.Select("ParentId=" + PId);
            for (int i = 0; i < dr.Length; i++)
            {
                //添加一行数据
                DataRow row = newData.NewRow();
                row["Id"] = int.Parse(dr[i]["Id"].ToString());
                row["Title"] = dr[i]["Title"].ToString();
                row["ParentId"] = int.Parse(dr[i]["ParentId"].ToString());
                row["ClassList"] = dr[i]["ClassList"].ToString();
                row["ClassLayer"] = int.Parse(dr[i]["ClassLayer"].ToString());
                row["SortId"] = int.Parse(dr[i]["SortId"].ToString());
                row["PageUrl"] = dr[i]["PageUrl"].ToString();
                row["KindId"] = int.Parse(dr[i]["KindId"].ToString());
                newData.Rows.Add(row);                this.GetChannelChild(oldData, newData, int.Parse(dr[i]["Id"].ToString()));
            }
        }

解决方案 »

  1.   

    没设置停止的条件,你递归返回上一层后继续执行了。你需要设置一个条件break或return
      

  2.   

    由Pid=0得到两条记录 开始循环(A)循环第一条-》继续查找Pid为当前ID的子集,往下递归-》开始循环,检测没有记录,完毕,返回循环(A)
    循环第二条-》继续查找Pid为当前ID的子集,往下递归-》开始循环,检测没有记录,完毕,返回循环(A)A结束
      

  3.   

    代码就不看了。
    什么叫递归,比如说你有一个函数GetChannelChild
    在函数的实现内部,又调用了GetChannelChild,那么就是递归。