Reputation: 43
I have two models, Category and ExternalResources:
Category
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; }
}
The variable called IsInActivity is the one I use to know whether to show on the list or not.
I want to show a list with the parents and just their childrens that has the variable IsInActivity set on true
I made a function that returns the parents that contains at least 1 child that has the value in true, but what I want is that it only returns the children that have IsInActivity in true.
public List<Category> ContainsResources(List<Category> qry)
{
List<Category> lstResourceIsInActivity = qry.Where(p => p.ExternalResources.Any(c => c.IsInActivity = true)).ToList();
return lstResourceIsInActivity;
}
Is there any way to do this with Linq?.
[UPDATED]
Already resolved my previous doubt, another doubt arose, in this case this returns the subcategories but not the parent categories if this has a subcategory(parent) with a selected child.
I made this function but it returns what I mentioned above:
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;
}
How to solve this with LinQ?
Upvotes: 1
Views: 531
Reputation: 5787
You can try this to reset your ExternalResources
collections only to itens where IsInActivity == true
:
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;
}
Upvotes: 0
Reputation: 1503779
Assuming you don't want to actually modify the Category
objects, you'll need to create new ones with the filtered resources in.
For example:
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();
Note that I haven't populated ParentCategory
or Subcategories
here. If you need those, you'll need to do significantly more work to make sure you keep referential integrity etc.
Upvotes: 1