我知道必须有一个简单的解决方案。
我有一个Category / Subcategory树。类别是顶级(无父类别ID)或子类别(具有父类别ID)。
我的班级:
public class Category
{
public int CategoryId { get; set; }
public int WebsiteId { get; set; }
public Nullable<int> ParentCategoryId { get; set; }
}
我的LINQ:
IList<Category> categories = db.Categories
.Where(c => c.WebsiteId == websiteId)
.Include(c => c.SubCategories)
.ToList();
问题......如果我有以下内容:
我在类别列表和类别1的子类别中返回了类别1a。
我得到了这个:
我尝试用一些不合理的混乱来剥离它,这是一种4种递归方法和70行字典构建和剥离,如果有人想看到它我可以发布它(它不起作用)
但是,如果有一些方法来制作LINQ来摆脱那些重复,那将是理想的。
提前非常感谢!
答案 0 :(得分:1)
如果.Include()
加入了子类别,那么您应该能够完全从初始列表中过滤掉子类别。哪个是具有父类别值的任何东西。像这样:
db.Categories
.Where(c => c.WebsiteId == websiteId)
.Where(c => c.ParentCategoryId == null) // filter sub-categories
.Include(c => c.SubCategories)
.ToList();
答案 1 :(得分:1)
@David的答案是正确的,但是只有当您的类别结构是一层深层时才会有效。
下面的代码从数据库中选择一个平面列表并将其转换为深层对象图。请注意AsNoTracking()
以防止任何更改写回数据库/操作图形的开销。
另请注意,大型列表会很慢,因为它会执行大量的linq查找等,并且还会从数据库中删除整个对象列表。
var categories = db.Categories.AsNoTracking()
.Where(c => c.WebsiteId == websiteId)
.ToList();
foreach (var category in categories.Where(c => c.ParentCategoryId.HasValue))
{
categories.First(c => c.CategoryId == category.ParentCategoryId.Value).SubCategories.Add(category);
}
categories.RemoveAll(c => c.ParentCategoryId.HasValue);
// categories is now a list of top level categories with deeply-nested sub-categories