2010-06-18 64 views
0

为了简单起见,“部分”对象包含以下属性:LINQ,以确定是否孩子存在

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实现这一目标的最佳方式是什么?

谢谢

+0

无需调用AsQueryable。那什么都不做。 – 2010-06-18 17:37:57

回答

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()); 

然后是群组加入技术,这应该相当高效:

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

感谢您的及时响应 - 完美! – 2010-06-18 17:44:06

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; 
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" } 
}; 

的查询将返回阿尔法,布拉沃,和苹果的列表。

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);