2010-06-18 161 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);