我有一个类别表,它被设置为允许无限数量的子类别级别。我想模仿以下内容:
需要说明的是子类可以有子类。例如。父猫 -> 级别 1 -> 级别 2 -> 级别 3 等
我的类别表有两列,CategoryName
和 ParentID
。
将正确的类别分配给产品时将使用此列表框。
这个怎么写?
编辑
为了响应 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);
}
}
}
这是即将完成的工作:
最佳答案
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/