问题是我不明白如何使用 LINQ 获取所有类别和子类别并将它们添加到列表中以便在 View 中显示它们。
public class Category
{
public int ID { get; set; }
public string Title { get; set; }
public int? ParentID { get; set; }
public virtual Category Parent { get; set; }
}
目前我只有这个方法可以获取所有的类别。
public async Task<IEnumerable<Category>> GetAllCategories()
{
return await _context.Categories.ToListAsync();
}
这是我想要实现的:
最佳答案
所以,如果我从这些数据开始:
var categories = new List<Category>()
{
new Category() { ID = 0, ParentID = null, Title = "First Link" },
new Category() { ID = 1, ParentID = null, Title = "Second Link" },
new Category() { ID = 2, ParentID = null, Title = "Third Link" },
new Category() { ID = 3, ParentID = null, Title = "Fourth Link" },
new Category() { ID = 4, ParentID = null, Title = "Fifth Link" },
new Category() { ID = 5, ParentID = 0, Title = "First Child Link" },
new Category() { ID = 6, ParentID = 0, Title = "Second Child Link" },
new Category() { ID = 7, ParentID = 0, Title = "Third Child Link" },
new Category() { ID = 8, ParentID = 6, Title = "First Grandchild Link" },
new Category() { ID = 9, ParentID = 6, Title = "Second Grandchild Link" },
new Category() { ID = 10, ParentID = 6, Title = "Third Grandchild Link" },
};
...那么我可以这样做:
var lookup = categories.ToLookup(x => x.ParentID);
这会创建一个可用于查找任何父 ID 的所有子代的查找。在您的情况下,您应该能够执行 _context.Categories.ToLookup(x => x.ParentID);
。您可能需要在 .ToLookup
之前弹出一个 .ToArray()
。
好处是这只会访问数据库一次。
现在递归遍历数据变得容易了。以下是三种方法:
(1)
Func<ILookup<int?, Category>, int?, int, IEnumerable<string>> formatTree = null;
formatTree = (l, p, i) =>
from c in l[p]
from t in new[] { "".PadLeft(i * 4) + c.Title }.Concat(formatTree(l, c.ID, i + 1))
select t;
(2)
public IEnumerable<string> FormatTree(ILookup<int?, Category> lookup, int? parent, int indent)
{
return
from c in lookup[parent]
from t in new[] { "".PadLeft(indent * 4) + c.Title }.Concat(FormatTree(lookup, c.ID, indent + 1))
select t;
}
(3)
public IEnumerable<string> FormatTree2(ILookup<int?, Category> lookup, int? parent, int indent)
{
foreach (var category in lookup[parent])
{
yield return "".PadLeft(indent * 4) + category.Title;
foreach (var descendant in FormatTree2(lookup, category.ID, indent + 1))
{
yield return descendant;
}
}
}
这三者都以相同的方式做同样的事情,只是语法不同而已。
我得到这个输出:
First Link First Child Link Second Child Link First Grandchild Link Second Grandchild Link Third Grandchild Link Third Child Link Second Link Third Link Fourth Link Fifth Link
不清楚您的确切输出是什么 - 我假设您不希望创建 PNG 图像 - 但您应该能够使用它来获得您需要的东西。
关于c# - Linq 类别和子类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35820398/