我一直在挖这个。
public class Person
{
public string Name { get; set; }
public string Age { get; set; }
public List<Person> Children { get; set; }
}
我想要一个LINQ查询来查找&#34;此集合中Age > 4
的所有人&#34;。
注意:您必须遍历Person
+ Children
集合的集合,因此每个子对象的Person
集合将Children
变为null
{{1}} }。
答案 0 :(得分:3)
首先,我无法理解为什么您的所有属性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)) //this line do recursive magic
.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
实体上生成对DB的查询。因此,如果你有很多人和深层次,那么你需要花费大量的机器时间。在这种情况下,您应该使用 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);
您现在可以随时更改您要使用功能的条件。
答案 1 :(得分:3)
创建访问者。在此示例中,通过实现帮助程序类:
public static class Helpers
public static IEnumerable<Person> GetDescendants(this Person person)
{
foreach (var child in person.Children)
{
yield return child;
foreach (var descendant in child.GetDescendants())
{
yield return descendant;
}
}
}
这是&#34;收益率回归很多的时代之一。会很有用。
答案 2 :(得分:1)
如果你确保自动创建.Children
,那么这可行:
Func<Person, Func<Person, bool>, Person> clone = null;
clone = (p, f) => f(p) ? new Person()
{
Name = p.Name,
Age = p.Age,
Children = p.Children.Select(c => clone(c, f)).Where(x => x != null).ToList(),
} : null;
var olderThan4 = clone(person, p => p.Age > 4);
是的,就是这样。实际上有三行。
如果您从这些数据开始:
var person = new Person()
{
Name = "Fred", Age = 30,
Children = new List<Person>()
{
new Person() { Name = "Bob", Age = 7, },
new Person() { Name = "Sally", Age = 3, }
},
};
...然后你得到这个结果:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
private List<Person> _children = null;
public List<Person> Children
{
get
{
if (_children == null)
{
_children = new List<Person>();
}
return _children;
}
set
{
_children = value;
}
}
}