如何递归获取类别及其子类别的子类别

时间:2013-04-19 09:00:05

标签: c# asp.net-mvc recursion

我正在尝试绘制我的网站地图,如下所示

 <ul>
       <li>Cat1</li>           
       <li>Cat2                
             <ul class='sub2'>                     
                <li>Cat21</li>           
                <li>Cat22</li>
                <li>Cat23
                      <ul class='sub23'>                     
                            <li>Cat231</li>           
                            <li>Cat232</li>
                            <li>Cat233                                
                                   <ul class='sub233'>                     
                                      <li>Cat2331</li>           
                                      <li>Cat2332</li>
                                      <li>Cat2333</li>
                                   </ul>
                            </li>
                      </ul>
                 </li>
             </ul>
       </li>     
       <li>Cat3
             <ul class='sub3'>                     
                <li>Cat31</li>           
                <li>Cat32</li>
                <li>Cat33</li>
             </ul>
       </li>
       <li>Cat4</li>
 </ul>

地图提供者是一个PostCategory对象列表

 List<PostCategory> MapProvider=new List<PostCategory>();
///....MapProvider.add(...);
CategoryMapViewModel siteMap=new CategoryMapViewModel(MapProvider);
var map=siteMap.Map.ToString();

和PostCategory对象

public class PostCategory{
    [Key]
    public int? CategoryId{get;set;}

    [StringLength(20/*50*/,MinimumLength=3)]
    public string Name{get;set;}

    [StringLength(250)]
    public string Description { get; set; }

    //relationship
    public int? IdPostCategoryParent { get; set; }
    }

我写了一些东西,但它对子类别的子类别不起作用递归:例如:它适用于sub2但不适用于sub23,sub332,sub ....

这是我的CategoryMapViewModel类

public class CategoryMapViewModel
{
    public HtmlString Map { get; private set; }
    private List<int?> TakenIds = new List<int?>();
    public CategoryMapViewModel(List<PostCategoryModels> categoriesModels)
    {
        string map = "";
        map = BuildCategoriesMap(categoriesModels, map);
        this.Map = new HtmlString(map);
    }

    private string BuildCategoriesMap(List<PostCategoryModels> categories, string map)
    {
        if (categories != null && categories.Count > 0)
        {
            map += "<ul>";
            foreach (PostCategoryModels cat in categories)
            {
                if ((!cat.CategoryId.HasValue) || (cat.CategoryId.HasValue && (!TakenIds.Contains(cat.CategoryId))))
                {
                    map += "<li>" + cat.Name;
                    List<PostCategoryModels> subCats = categories.Where(c => c.IdPostCategoryParent == cat.CategoryId).ToList();
                    if (subCats.Count() > 0)
                    {
                        //map += BuildCategoriesMap(subCats, map);
                        //BuildCategoriesMap(subCats, map);
                        map += BuildCategoriesMap(subCats, "");
                    }
                    map += "</li>";
                }
                TakenIds.Add(cat.CategoryId);
            }
            map += "</ul>";
        }
        return map;
    }
}
我错了吗?有人可以给我最好最简单的方法吗?如果有,请这样做! 亲切的问候!

1 个答案:

答案 0 :(得分:2)

问题在于您正在搜索子项的类别,但在处理直接子项时,您只传递直接子项,因此在搜索子类时,没有匹配项。

一种解决方案是在类中保留对类别的引用,并在搜索子类别时使用它。

即:

public class CategoryMapViewModel
{
    public HtmlString Map { get; private set; }
    private List<int?> TakenIds = new List<int?>();
    private List<PostCategoryModels> _categories;

    public CategoryMapViewModel(List<PostCategoryModels> categoriesModels)
    {    
        _categories = categoriesModels ?? new List<PostCategoryModels>();
        string map = BuildCategoriesMap(_categories);
        this.Map = new HtmlString(map);
    }

    private string BuildCategoriesMap(List<PostCategoryModels> categories)
    {
        var map = "";
        if (categories.Count > 0)
        {
            map += "<ul>";
            foreach (PostCategoryModels cat in categories)
            {
                if ((!cat.CategoryId.HasValue) || (cat.CategoryId.HasValue && (!TakenIds.Contains(cat.CategoryId))))
                {
                    map += "<li>" + cat.Name;
                    List<PostCategoryModels> subCats = _categories.Where(c => c.IdPostCategoryParent == cat.CategoryId).ToList();
                    map += BuildCategoriesMap(subCats);
                    map += "</li>";
                }
                TakenIds.Add(cat.CategoryId);
            }
            map += "</ul>";
        }
        return map;
    }
}

我还拿出了一些冗余线