首先,我不明白为什么你的所有属性都是 private
,而 Age
不是 int
类型。所以我的类看起来像这样:
public partial class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<Person> Childrens { get; set; }
}
注意
partial
关键字。这个关键字可以让你把类的逻辑分离到不同的文件中,当你需要在类中创建一些自定义逻辑时非常有用。
然后我只需在另一个文件中创建这个方法:
public partial class Person
{
public Person GetPersonWithChindren(int maxAge)
{
return new Person
{
Age = this.Age,
Name = this.Name,
Childrens = this.Childrens != null
? this.Childrens
.Where(x => x.Age < maxAge)
.Select(x => x.GetPersonWithChindren(maxAge))
.ToList()
: null
};
}
}
正如您所看到的,该方法检查每个孩子的 Age
,如果 Age
正确,则检查下一层级的结构,直到 Childrens
为 null
。
因此,您可以像这样使用它:
var person = new Person()
{
//initialisation of your collection here
}
//result will contains only nodes where Person have age < 4 and Childs that have age < 4
var result = person.GetPersonWithChindren(4);
请注意,这个解决方案在使用
linqToEntities 时可以正常工作。但是如果你使用
LinqToSQL,这个表达式会对每个
Person
实体产生数据库查询。因此,如果你有很多人和深层次的层次结构,它将花费你很多机器时间。在这种情况下,你应该使用
CTE 编写存储过程,而不是 LinQ 查询。
更新:
你甚至可以通过使用
Func<T>
类编写更通用的解决方案,如下所示:
public partial class Person
{
public Person GetPersonWithChindren(Func<Person, bool> func)
{
return new Person
{
Age = this.Age,
Name = this.Name,
Childrens = this.Childrens != null
? this.Childrens
.Where(x => func(x))
.Select(x => x.GetPersonWithChindren(func))
.ToList()
: null
};
}
}
然后你可以像这样使用它:
var result = person.GetPersonWithChindren(x => x.Age < 4)
您现在可以随时更改要在何处使用您的函数的标准。
public class Person : List<Person> { public string Name { get; set; } public string Age { get; set; } }
替换这个类,从而避免每次创建Children
属性的需要。这样还能让你使用集合初始化器。 - Enigmativity