user2208746
user2208746

Reputation: 83

How to filter list with linq for sub list?

I have the following classes:

    public class Customer
    {
        public string CustomerId;
        public string CustomerName;
        public List<CustomerOrder> Orders;
    }

    public class CustomerOrder
    {
        public string OrderName;
        public string Account;
        public string PassFail;
    }

What I am trying to do is I need to get only Customer records that have had zero PassFails = "F" for that account. So for example if I have CustomerId = 1 and two Orders for Account = "1000" one PassFail = "P" and one = "F". I don't want the Customer record in my result set. So I have the following so far:

//get accounts where any order failed
var failedAccounts = customers.SelectMany(s => s.Orders)
                    .Where(w => w.PassFail == "F")
                    .GroupBy(g => g.Account)
                    .Select(g => new
                    {
                        Account = g.Key
                    });

I am stuck at this point as I am trying to get my customers list where all orders have passed for the account. Hope this makes sense. I want to still keep the Order record as is I need to know if one of the orders did pass but at a later stage I need to filter out the Customer records. Thanks all

Upvotes: 0

Views: 332

Answers (2)

Rufus L
Rufus L

Reputation: 37080

customers.SelectMany() in the sample code is selecting all the Orders from the customers (but not the customers themselves). We can use customers.Where() to select Customers, and then to filter on accounts that have any order whose PassFail value is "F", we can use the Any extension method (from System.Linq):

var failedAccounts = customers.Where(s => s.Orders.Any(o => o.PassFails == "F"));

Conversly, if we want to find the customers whose orders are all passed, we can use All:

var passedAccounts = customers.Where(s => s.Orders.All(o => o.PassFails == "P"));

Upvotes: 0

feihoa
feihoa

Reputation: 517

customers.Where(s => s.Orders.All(o => o.PassFails == "F"))

and then add anything you want

Upvotes: 1

Related Questions