Linq 查询,该查询检索具有集合的子项的父项/子项
本文关键字:查询 子项 检索 Linq 集合 | 更新日期: 2023-09-27 18:33:51
我有一个自引用Category
类,如果它至少有一个子类别并且在集合中至少有一个或多个活动(ICollection<Activity>
(,我想从中检索父类别和所有相应的子类别。
这也适用于儿童的孩子,因为只有当存在至少具有 1 个或多个活动的儿童类别时,才应返回这些类别。
如果没有至少包含 1 个或多个活动的子类别,则不应返回父项或子项Category
。
查询应将父Category
作为实际Category
对象返回,而不仅仅是CategoryId
。这可能吗?
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual Category Parent { get; set; }
public virtual ICollection<Category> Children { get; set; }
public virtual ICollection<Activity> Activities { get; set; }
}
更新 1
部分有效的查询:
var categories = _db.Categories
.Where(x => x.Parent != null && x.Activities.Count > 0)
.GroupBy(x => x.ParentId)
.Select(g => new { Parent = g.Key, Children = g.ToList() }).ToList();
让我们从小一点开始,因为您要创建的查询有些复杂。我们将自下而上创建您的查询。首先,您希望消除没有任何子类别的类别,这些子类别至少具有一个或多个活动。让我们做一个Predicate
,在一个级别上为应该包含的内容返回true
,为应该排除的内容返回false
。我们将分两个阶段进行。首先,让我们创建一个谓词,为具有活动的类别返回true
:
Predicate<Category> hasActivities = cat => cat.Activities.Any();
其次,让我们创建一个Predicate
,为那些具有具有活动的子类别的类别返回true
:
Predicate<Category> hasChildWithActivities =
parentCat => parentCat.Children.Any(hasActivities);
现在让我们创建一个过滤器查询,该查询将过滤给定Category
的后代。为此,我们将创建一个Func
,该采用父Category
,执行逻辑并返回更新的Category
:
Func<Category, Category> getFilteredCategory =
parentCat =>
{
parentCat.Children = parentCat.Children
.Where(hasChildWithActivities)
.Select(getFilteredCategory);
return parentCat;
});
请注意,这相当于:
Func<Category, Category> getFilteredCategory = delegate(Category parentCat)
{
parentCat.Children = parentCat.Children
.Where(hasChildWithActivities)
.Select(getFilteredCategory);
return parentCat;
};
在你的OP中,你提到你也想过滤父母。您可以通过遍历到顶级并运行此查询,或者通过使用"joins"或更复杂的"select"语句创建单独的查询,在父级上使用相同的逻辑。恕我直言,后者可能会很混乱,我建议不要这样做。如果你也需要将逻辑应用于父级,那么首先向上遍历树。无论哪种方式,这都应该给你一个好的开始。
如果您有任何问题,请告诉我。祝你好运,编码愉快!:)