从LINQ结果中删除重复项

时间:2017-09-07 23:57:50

标签: c# .net linq

我知道必须有一个简单的解决方案。

我有一个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类(第1类的子目录)
  • 第2类
  • 第3类

我在类别列表和类别1的子类别中返回了类别1a。

我得到了这个:

  • 第1类
    • 类别1a
  • 类别1a //此重复内容需要发布!
  • 第2类
  • 第3类

我尝试用一​​些不合理的混乱来剥离它,这是一种4种递归方法和70行字典构建和剥离,如果有人想看到它我可以发布它(它不起作用)

但是,如果有一些方法来制作LINQ来摆脱那些重复,那将是理想的。

提前非常感谢!

2 个答案:

答案 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