Reputation: 2237
I trying to filter data using Linq. But I don't know where I'm doing wrong.
Here is the scenario:
I've two classes:
public class Category
{
public int Id { get; set; }
public bool Status { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public int Id { get; set; }
public bool Status { get; set; }
}
Here is how, I'm populating the categories list:
var categories = new List<Category>();
for (int i = 1; i <= 5; i++)
{
var category = new Category
{
Id = i,
Status = true
};
categories.Add(category);
}
foreach (var category in categories)
{
var products = new List<Product>();
for (int i = 1; i <= 5; i++)
{
var product = new Product
{
Id = i,
Status = (i % 2 == 0)
};
products.Add(product);
}
category.Products = products;
}
and I'm trying to get categories having product as status = true.
var filter = categories.Where(c => c.Products.Any(p => p.Status)).ToList();
but it's showing all of the products even the false one too.
I only want those products in the respective catalogs that are having status = true
output should be like this:
category1-> product2, product4
category2 -> product2, product4
category3 -> product2, product4
category4 -> product2, product4
category5 -> product2, product4
Upvotes: 1
Views: 4133
Reputation: 32521
You can try this to get categories with those products that their status
is true
var newCategories = categories.Select(
i => new Category {
Id = i.Id,
Status = i.Status,
Products = i.Products.Where(p => p.Status).ToList()
})
.ToList();
EDIT If you add a constructor for your Category class like this:
public class Category
{
public int Id { get; set; }
public bool Status { get; set; }
public List<Product> Products { get; set; }
public Category(int id, bool status)
{
this.Id = id;
this.Status = status;
}
}
Then you do this (slightly better code than previous one)
var newCategories = categories.Select(
i => new Category(i.Id, i.Status) {
Products = i.Products.Where(p => p.Status).ToList()
})
.ToList();
Upvotes: 5
Reputation: 138
You're showing all the categories, which carry at least one Product == true. Therefore every product which has a true sibling in the same category will be listed.
This is also because you are basically not querying products but categories.
You could go:
var products = categories.SelectMany(c => c.Products).Where(p => p.Status).ToList();
Upvotes: 3
Reputation: 831
You're showing all the categories with one or more products with status true. That's why you get all of them because every category has at least a product with status true.
Upvotes: 1
Reputation: 405
In your code, you're adding products this way:
for (int i = 1; i <= 5; i++)
{
var product = new Product
{
Id = i,
Status = (i % 2 == 0)
};
products.Add(product);
}
You will have 5 products in each category, 2 of which will have a status of true. You are selecting all categories that have at least one status == true product, which is every category.
Upvotes: 2