Linq查询检索带有集合的子项的父/子

时间:2014-12-09 13:00:40

标签: c# sql linq entity-framework

我有一个自引用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();

1 个答案:

答案 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;声明。恕我直言,后者可能会很乱,我会反对它。如果您还需要将逻辑应用于父项,则首先遍历树。不管怎样,这应该会给你一个良好的开端。


如果您有任何疑问,请与我们联系。祝你好运,编码愉快! :)