我有一个自引用Category
类,如果它至少有一个子类别且至少有一个或多个活动(ICollection<Activity>
),我想从中检索父类别和所有相应的子类在集合中。
这也适用于儿童的孩子,因为只有在有至少一项或多项活动的儿童类别时才能退回。
如果没有包含至少一项或多项活动的子类别,则父项或子项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();
答案 0 :(得分:1)
让我们开始变小,因为您要创建的查询有点复杂。我们将自下而上创建您的查询。首先,您希望消除没有任何具有至少一个或多个活动的子类别的类别。让我们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;
};
请注意,这相当于:
{{1}}
在你的OP中,你提到你也想过滤父母。您可以通过遍历最高级别并运行此查询,或通过使用&#34; join&#34;创建单独的查询,在父项上使用相同的逻辑。或更复杂的&#34;选择&#34;声明。恕我直言,后者可能会很乱,我会反对它。如果您还需要将逻辑应用于父项,则首先遍历树。不管怎样,这应该会给你一个良好的开端。
如果您有任何疑问,请与我们联系。祝你好运,编码愉快! :)