У меня есть следующая схема сущностей:
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.
Почему в вашем классе Container есть участник Forest и участник Tree? Каково значение члена Tree? Вы говорите «Отфильтровать коллекцию лесов», но в вашем коде нет коллекции Forest. И что означает «с отфильтрованными деревьями и листьями»?





Вы можете довольно легко создать набор фильтров 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
);
Если в вашей иерархии мало деревьев и много листьев, вы можете сначала изменить поиск на поиск по деревьям, а затем выполнить отдельный поиск по дереву->лист, даже если это делает два прохода по деревьям.
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
);
вы хотите отфильтровать его на уровне базы данных или на уровне приложения?