我遇到了问题。
我有一个孙子系列,我想使用LINQ变成祖父母对象的集合。子对象具有父级的导航属性。我曾经用祖父母的名字尝过一组,但后来我被一根绳子困住了。
我的祖父母班级看起来像这样:
GrandParent类
public class GrandParentBLL
{
public GrandParentBLL()
{
Parents= new List<Parent>();
}
public int ID { get; set; }
public int Number { get; set; }
public string Name { get; set; }
public ICollection<ParentBLL> Parents{ get; set; }
}
儿童班:
Child class
public class ParentBLL
{
public ParentBLL()
{
Children= new List<Child>();
}
public int ID { get; set; }
public int Number { get; set; }
public string Name { get; set; }
public GrandParentBLL GrandParent { get; set; }
public ICollection<ChildBLL> Children { get; set; }
}
GrandChild班:
public class ChildBLL
{
public ChildBLL()
{
}
public int ID { get; set; }
public int Number { get; set; }
public string Name { get; set; }
public ParentBLL Parent{ get; set; }
}
现在我得到了一个孙子对象列表,其中每个对象可以有不同的父对象或祖父对象。我可以使用navigation属性访问父级。我想获得一个祖父母对象列表,其中包含每个祖父母的相应子集合。
我尝试了以下内容:
var grandparents = Children.GroupBy(x => x.Parent.GrandParent).Select(d=>d.Key).ToList();
然后我为grandChildren集合中的每个对象获得一个祖父对象,尽管只有2个不同的祖父母。
答案 0 :(得分:1)
如果您想获得唯一的granparent实体,您的查询应该是
var grandparents = grandChildren
.Select(c => c.Parent) // --> get all the grand children's parents
.Select(p => p.GrandParent) // --> get all the GrandParents from each of the Parents above
.Distinct();
更新:因此,如果父对象不包含子集合,则根据您的注释以及接受的答案。这是一种水合父对象的方法:
IEnumerable<ParentBLL> parents = grandChildren
.Select(gc => gc.Parent)
.Distinct()
.Pipe(p => p.GrandChildren = grandChildren.Where(gc => gc.Parent.ID == p.ID).ToList());
IEnumerable<GrandParentBLL> grandparents = parents
.Select(p => p.GrandParent).Distinct()
.Pipe( gp => gp.Parents = parents.Where(p => p.GrandParent.ID == gp.ID).ToList());
此解决方案使用.Pipe
,“对源序列中的每个元素执行给定的操作并生成它”。这是MoreLinq的扩展方法。所以你需要添加对这个包的引用。
答案 1 :(得分:1)
从您的示例中不清楚每个班级是否有自己的直系孩子的集合。如果他们这样做,答案很简单:
Dictionary<GrandParent,List<Child>> results = grandparents.ToDictionary
(
g => g,
g => g.Parents.SelectMany( p => p.Children ).ToList()
);
如果父母不了解自己的孩子,并且只有孩子知道他们的直系父母,那么还有更多的工作要做,我将分三步完成:
步骤1.首先获得父母和我们可以重复使用的祖父母的调查员:
var parents = children.Select( c => c.Parent ).Distinct();
var grandParents = parents
.Select( p => p.GrandParent )
.Distinct();
步骤2.现在修改代码以将grandParents
更改为Dictionary<GrandParent,List<Parent>>
:
var children = new List<ChildBLL>();
var parents = children.Select( c => c.Parent ).Distinct();
var grandParents = parents
.Select( p => p.GrandParent )
.Distinct()
.ToDictionary
(
g => g,
g => parents.Where( p => p.GrandParent == g )
);
步骤3.添加代码以将Dictionary<GrandParent,List<Parent>>
转换为Dictionary<Grandparent,List<Child>>
:
var parents = children.Select( c => c.Parent ).Distinct();
var grandParents = parents
.Select( p => p.GrandParent )
.Distinct()
.ToDictionary
(
g => g,
g => parents.Where( p => p.GrandParent == g )
)
.ToDictionary
(
pair => pair.Key,
pair => pair.Value.SelectMany
(
p => children.Where( c => c.Parent == p )
)
);
当你完成后,你会得到一个字典,其中键是GrandParent,值是其孙子的List<Children>
。