如何根据他们在Linq的孩子的价值获得父母和孩子的名单?

时间:2018-05-17 14:22:13

标签: c# asp.net-mvc linq

我有两个模型,Category和ExternalResources:

分类

public partial class Category
{
    public long CategoryID { get; set; }
    public string Name { get; set; }
    public Nullable<long> ParentCategoryID { get; set; }

    public virtual ICollection<Category> Subcategories { get; set; }
    public virtual Category ParentCategory { get; set; }
    public virtual ICollection<ExternalResource> ExternalResources { get; set; }
}

ExternalResources

public partial class ExternalResource
{
    public string DisplayText { get; set; }
    public string URL { get; set; }
    public long CategoryID { get; set; }
    public int ExternalResourceID { get; set; }
    public bool SupportItem { get; set; }
    public bool IsInActivity { get; set; }

    public virtual Category Category { get; set; }
}

名为 IsInActivity 的变量是我用来知道是否在列表中显示的变量。

我想要显示一个列表,其中包含父母和他们的孩子,其中 IsInActivity 设置为 true

我创建了一个函数,它返回包含至少1个值为true的子节点的父节点,但我想要的是它只返回IsInActivity为true的子节点。

public  List<Category> ContainsResources(List<Category> qry)
{
    List<Category> lstResourceIsInActivity =  qry.Where(p => p.ExternalResources.Any(c => c.IsInActivity = true)).ToList();

    return lstResourceIsInActivity;
}

有没有办法用Linq做到这一点?。

[增订]

已经解决了我之前的疑问,另一个疑问出现了,在这种情况下,如果它有一个带有选定子项的子类别(父),则返回子类别但不返回父类别。

我做了这个功能,但它返回我上面提到的内容:

public List<Category> ContainsResources(List<Category> qry)
{
            List<Category> lstResourceIsInActivity = qry.Where(c => c.ExternalResources.Any(r => r.IsInActivity)).Select(c => new Category
            {
                CategoryID = c.CategoryID,
                Name = c.Name,
                ParentCategoryID = c.ParentCategoryID,
                Subcategories = c.Subcategories.Where(b => b.ExternalResources.Any(r => r.IsInActivity) && b.ParentCategoryID != null).Select(b => new Category
                {
                    CategoryID = b.CategoryID,
                    Name = b.Name,
                    ParentCategoryID = b.ParentCategoryID,
                    ExternalResources = b.ExternalResources.Where(r => r.IsInActivity).ToList()
                }).ToList(),
                ParentCategory = c.ParentCategory,
                ExternalResources = c.ExternalResources.Where(r => r.IsInActivity).ToList()
            })
         .ToList();

            return lstResourceIsInActivity;
}

如何用LinQ解决这个问题?

2 个答案:

答案 0 :(得分:1)

假设您不想实际修改Category个对象,则需要使用已过滤的资源创建新的对象。

例如:

public List<Category> ContainsResources(List<Category> query) =>
    query.Where(c => c.ExternalResources.Any(r => r.IsInActivity))
         .Select(c => new Category
                 {
                     CategoryID = c.CategoryID,
                     Name = c.Name,
                     ParentCategoryID = c.ParentCategoryID,
                     ExternalResources = c.ExternalResources.Where(r => r.IsInActivity).ToList()
                 })
         .ToList();

请注意,此处尚未填充ParentCategorySubcategories。如果您需要这些,您需要做更多的工作,以确保您保持参照完整性等。

答案 1 :(得分:0)

您可以尝试将此ExternalResources个收藏集重置为IsInActivity == true的<{1}}:

public List<Category> ContainsResources(List<Category> qry)
{
    List<Category> lstResourceIsInActivity =  qry.Where(p => p.ExternalResources.Any(c => c.IsInActivity)).ToList();

    lstResourceIsInActivity.ForEach(c => c.ExternalResources = c.ExternalResources.Where(e => e.IsInActivity).ToList());

    return lstResourceIsInActivity;
}