为简单起见,“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实现此目的的最佳方法是什么?
由于
答案 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);