c# - 如何使用递归编程填充包含多个类别的列表框

标签 c# asp.net linq-to-sql recursion

我有一个类别表,它被设置为允许无限数量的子类别级别。我想模仿以下内容: enter image description here

需要说明的是子类可以有子类。例如。父猫 -> 级别 1 -> 级别 2 -> 级别 3 等

我的类别表有两列,CategoryNameParentID

将正确的类别分配给产品时将使用此列表框。

这个怎么写?

编辑

为了响应 thedugas,我不得不修改您的答案以适应我的情况。我发现了一些需要修复的错误,但下面是最终的有效解决方案。

protected void Page_Load(object sender, EventArgs e)
    {
        using (DataClasses1DataContext db = new DataClasses1DataContext())
        {

        var c = db.Categories.Select(x => x);

        List<Category> categories = new List<Category>();
        foreach (var n in c)
        {
            categories.Add(new Category()
            {
                categoryID = n.categoryID,
                title = n.title,
                parentID = n.parentID,
                isVisible = n.isVisible
            });
        }
        List<string> xx = new List<string>();

        foreach (Category cat in categories)
        {
            BuildCatString(string.Empty, cat, categories, xx);
        }

        ListBox1.DataSource = xx;
        ListBox1.DataBind();

    }
}

private void BuildCatString(string prefix, Category cat, IEnumerable<Category> categories, List<string> xx)
{
    if (cat.parentID == 0)
    {
        xx.Add(cat.title);
        prefix = cat.title;
    }

    var children = categories.Where(x => x.parentID == cat.categoryID);
    if (children.Count() == 0)
    {
        return;
    }

    foreach (Category child in children)
    {
        if(prefix.Any())
        {
        xx.Add(prefix + "/" + child.title);
        BuildCatString(prefix + "/" + child.title,
            child, categories, xx);
        }
    }

}

这是即将完成的工作: enter image description here

最佳答案

Nick 在对 another question 的评论中问我如何在不使用任何递归的情况下使用 LINQ to Objects 解决此类问题。轻松完成。

假设我们有一个 Dictionary<Id, Category>将 id 映射到类别。每个类别都有三个字段:Id、ParentId 和 Name。假设 ParentId 可以为 null,以标记那些“顶级”类别。

所需的输出是一个字符串序列,其中每个字符串都是类别的“完全限定”名称。

解决方案很简单。我们首先定义一个辅助方法:

public static IEnumerable<Category> CategoryAndParents(this Dictionary<Id, Category> map, Id id)
{
    Id current = id;
    while(current != null)
    {
        Category category = map[current];
        yield return category;
        current = category.ParentId;
    }
}

还有这个辅助方法:

public static string FullName(this Dictionary<Id, Category> map, Id id)
{
    return map.CategoryAndParents(id)
              .Aggregate("", (string name, Category cat) =>
                cat.Name + (name == "" ? "" : @"/") + name);
}

或者,如果您希望避免可能效率低下的原始字符串连接:

public static string FullName(this Dictionary<Id, Category> map, Id id)
{
    return string.Join(@"/", map.CategoryAndParents(id)
                                .Select(cat=>cat.Name)
                                .Reverse());
}

现在查询很简单:

fullNames = from id in map.Keys
            select map.FullName(id);
listBox.DataSource = fullNames.ToList();

不需要递归。

关于c# - 如何使用递归编程填充包含多个类别的列表框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5348485/

相关文章:

linq-to-sql - LInq to sql 查询

.net - LINQ 有多快?

c# - CLR 中的动态 sql 连接字符串

c# - 如何在 Visual Studio 中关闭括号/引号自动完成

c# - 将图像从数据库绑定(bind)到 GridView 而不使用处理程序或 httphandler

asp.net - IIS AppPoolIdentity 和文件系统写入访问权限

c# - 在 WPF 中的 View 模型上应用模板样式

c# - 命名空间和类同名?

asp.net - 搜索邮政编码或城镇

c# - 在 LINQ to SQL 中创建按位运算符?