我有一个简单的人员层次结构(EntityFramework Codefirst)。
public class Person
{
[Key]
public int Id { get; set; }
public int? ParentId { get; set; }
[Required]
public string Name { get; set; }
// Navigation
[ForeignKey("ParentId")]
public virtual Person Parent { get; set; }
public virtual ICollection<Person> Children { get; set; }
}
我的目标:
我需要一个创建List<Person>
的方法,该方法是(1)由父母聚类,(2)按字母顺序按名称在每个级别上排序:
示例输出:
我可以使用嵌套循环轻松创建这种列表。但我相信这不会非常有效或优雅。但也许我错了。
你们中的任何人都有一个好主意/建议(也许是LINQ)?谢谢!
哦,我应该提到层次结构只是2级。所以,只有父母和孩子(但没有孙子孙女)。
答案 0 :(得分:2)
这会有用吗?
List<Person> sortPeople(List<Person> people)
{
List<Person> result = new List<Person>();
foreach (Person p in people.OrderBy(_ => _.Name).ToList())
{
result.Add(p);
result.AddRange(p.Children.OrderBy(_ => _.Name).ToList());
}
return result;
}
答案 1 :(得分:2)
var sortedPeople =
from p in people
orderby (p.Parent == null ? p.Name : p.Parent.Name),
p.Parent == null ? 1 : 2, // this ensures parents appear before children
p.Name
select p;
答案 2 :(得分:1)
只有在有两个级别并且我不知道这如何转换为SQL时才有效:
var parents = people.Select(person=>person.Parent == null);
var parentsWithChildrenGrouped =
parents
.SelectMany(parent=>parent.Children.Select(child=>new {Parent = parent, Child = child, Out = child}))
.Union(parents.Select(parent => new {Parent = parent, Child = null, Out = parent}))
.OrderBy(x=>x.Parent).ThenBy(x=>x.Child)
.Select(x=>x.Out);
此查询首先创建列表,其中每个项目都包含子项及其父项。然后它首先根据父母进行排序,然后按子进行排序。然后有第三个&#34; out&#34;定义行的用途的属性。
我知道这很容易转换为有效的SQL,但我不确定EF将如何处理它。