LINQ确定孩子是否存在

时间:2010-06-18 17:12:36

标签: c# linq

为简单起见,“Section”对象包含以下属性:

SectionId
ParentSectionId
Name

我目前有以下LINQ代码来获取给定部分的子部分:

List<Section> sections = SectionCache.GetAllSections();

sections.AsQueryable().Where(s => s.ParentSectionId == 10);

这给了我这个部分的所有孩子,SectionId为10(再次,为了简单起见),但是我需要进一步发展它,只包括他们自己有孩子的部分。在SQL中,我可能会这样做:

SELECT      Section.SectionId,
            Section.ParentSectionId,
            Section.Name
FROM        Section
INNER JOIN  Section children ON children.ParentSectionId = Section.SectionId
WHERE       Section.ParentSectionId = 10
GROUP BY    Section.SectionId,
            Section.ParentSectionId,
            Section.Name
HAVING      COUNT(children.SectionId) > 0

如何在LINQ中实现这一点/使用LINQ实现此目的的最佳方法是什么?

由于

4 个答案:

答案 0 :(得分:2)

这里有几种方法(这些非常相同)

IEnumerable<Section> query =
  sections.Where(s =>
    sections.Any(c => s.SectionId = c.ParentSectionId))
  );

IEnumerable<Section> query =
  from s in sections
  where (
   from c in sections
   where c.ParentSectionId == s.SectionId)
   select c).Any()
  select s;

或更优化:

ILookup<int, Section> childLookup =
  sections.ToLookup(c => c.ParentSectionId);
IEnumerable<Section> query =
  sections.Where(s => childLookup[s.SectionId].Any());

然后是groupjoin技术,它也应该非常有效:

IEnumerable<Section> query =
  from s in sections
  join c in sections
    on s.SectionId equals c.ParentSectionId
    into children
  where children.Any()
  select s;

答案 1 :(得分:1)

如果我正在阅读您的要求

,这里有一对想法
// one method
var query = from section in sections
            where sections.Any(s => s.ParentSectionId == section.SectionId)
            select section;

// another method 
var query2 = (from section in sections
                join child in sections
                on section.SectionId equals child.ParentSectionId
                select section).Distinct();

以这种方式填充列表

List<Section> sections = new List<Section>()
{
    new Section () { SectionId = 1, ParentSectionId = 0, Name = "Alpha" },
    new Section () { SectionId = 2, ParentSectionId = 0, Name = "Bravo" },
    new Section () { SectionId = 3, ParentSectionId = 0, Name = "Charlie" },
    new Section () { SectionId = 4, ParentSectionId = 1, Name = "Apple" },
    new Section () { SectionId = 5, ParentSectionId = 2, Name = "Banana" },
    new Section () { SectionId = 6, ParentSectionId = 4, Name = "Aardvark" },
    new Section () { SectionId = 7, ParentSectionId = 4, Name = "Antelope" }
};

查询将返回Alpha,Bravo和Apple。

答案 2 :(得分:0)

我更喜欢类似SQL的LINQ语法。它比流利的更具可读性。 : - )

        var sections = SectionCache.GetAllSections().AsQueryable();
        var filteredSections = from s in sections
                               let cc = (from c in sections
                                          where (c.ParentSectionId == s.SectionId)
                                          select c).Count()
                               where (s.ParentSectionId == 10) && (cc > 0)
                               select s;

答案 3 :(得分:0)

        List<Section> sections = new List<Section>();
        sections.Add(new Section { SectionId = 1, ParentSectionId = 0, Name ="S1" });
        sections.Add(new Section { SectionId = 2, ParentSectionId = 1, Name = "S2" });
        sections.Add(new Section { SectionId = 3, ParentSectionId = 1, Name ="S3" });
        sections.Add(new Section { SectionId = 4, ParentSectionId = 2, Name ="S4" });
        sections.Add(new Section { SectionId = 5, ParentSectionId = 2, Name ="S5" });

        var result = sections.GroupJoin(sections, p => p.SectionId, chld => chld.ParentSectionId, (p, chld) => new { Parent = p, Children = chld })
                           .Where(g => g.Children.Any())
                           .Select(g => g.Parent);