我有以下实体方案:
class Container
{
Forest Forest;
Tree Tree;
}
class Forest
{
int Id;
string Name;
List<Trees> Trees;
}
class Tree
{
int Id;
string Name;
Forest Forest;
List<Leaf> Leafs;
}
class Leaf
{
int Id;
string Name;
Tree Tree;
}
我有Forest
的集合,其中包含从数据库中读取的Trees and Leafs
。
如何执行以下操作:
根据以下规则过滤出Forests
的集合:
以森林条目为例,其中任一条目的[Name]
包含一些"filter value"
或那些Trees
[Name]
包含"filter value"
的人
或那些Leaf
[Name]
的人包含"filter value"
。
我需要返回森林的层次结构,而不是森林的平坦视图
我尝试展平结构以过滤条目,例如INNER JOIN
视图中的数据库表
IEnumerable<Container> containers;
var groupped = forests.Select(f => new {f.Forest, f.Tree})
.GroupBy(f => f.Forest)
.ToList().Select(fs => new {Forest = fs.Key, Leafes = fs.SelectMany(g => g.Tree.Leafes) }).ToDictionary(fx => fx.Forest, fx => fx.Leafes);
var flat = new List<Tuple<Forest, Tree, Leaf>>;
foreach (var i in groupped)
{
foreach (var l in i.Value)
{
flat.Add((i.Key, l.Tree, l));
}
}
flat.Where(d => d.Item1.Name.Contains("")
|| d.Item2.Name.Contains("")
|| d.Item3.Name.Contains(""));
但是实际上我不能在属性上将它们组合回到Forest -> Tree -> Leaf
因此,我不想有一个类似List<Tuple<Forest,Tree,Leaf>>
的表格结构,而是希望有一个普通集合List<Forest>
,其中过滤了Trees
和Leafs
。
答案 0 :(得分:0)
您可以很容易地从Container
列表中生成Containers
的过滤器集合,只需完全按照编写的方式实现所需的过滤器即可。 (这不是(不一定)最有效的搜索方式,但可能非常接近。)
var ans = src.Where(c => c.Forest.Name.Contains(fv) || // Forest name contains filter value
c.Forest.Trees.Any(t => t.Name.Contains(fv) || // a Tree name contains filter value
t.Leafs.Any(l => l.Name.Contains(fv))) // a Leaf name contains filter value
);
如果层次结构中的树木很少,叶子很多,那么您可能希望将搜索更改为首先搜索树木,然后进行单独的tree-> leaf搜索,即使这两次穿过树木也是如此。
var ans2 = src.Where(c => c.Forest.Name.Contains(fv) || // Forest name contains filter value
c.Forest.Trees.Any(t => t.Name.Contains(fv)) || // a Tree name contains filter value
c.Forest.Trees.Any(t => t.Leafs.Any(l => l.Name.Contains(fv))) // a Leaf name contains filter value
);