Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query c# List to limit children but return parents

Tags:

c#

linq

I have a nested list structure with Customers -> Orders -> OrderItems. I am trying to find a LINQ or other query that will return the Customers and their nested items where the OrderItem quantity = 1. However, it should not return any Orders or OrderItems where the quantity != 1.

I have tried this:

var customers2 = customers.Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)));

It correctly returns only Customers with order items quantity = 1, but it also returns all other Orders and Order Items as well.

I can get the desired results with a couple of For-each loops, but I would like to find something more elegant:

        foreach (var customer in customers2)
        {
            customer.Orders = customer.Orders.Where(o => o.OrderItems.Exists(oi => oi.Quantity == 1)).ToList();

            foreach (var order in customer.Orders)
            {
                order.OrderItems = order.OrderItems.Where(oi => oi.Quantity == 1).ToList();
            }
        }

Here is the object structure and some sample data.

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public List<Order> Orders { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
    public int CustomerId { get; set; }
    public DateTime OrderDate { get; set; }
    public bool Shipped { get; set; }
    public List<OrderItem> OrderItems { get; set; }
}

public class OrderItem
{
    public int OrderItemId { get; set; }
    public int OrderId { get; set; }
    public string ItemName { get; set; }
    public int Quantity { get; set; }
}

        var customers = new List<Customer>
        {
            new Customer
            {
                CustomerId = 1,
                Name = "Shawn",
                Address = "123 Main Street",
                Orders = new List<Order>()
                {
                    new Order()
                    {
                        OrderId = 100,
                        CustomerId = 1,
                        OrderDate = DateTime.Now,
                        Shipped = true,
                        OrderItems = new List<OrderItem>()
                        {
                            new OrderItem()
                            {
                                OrderItemId = 200,
                                OrderId = 100,
                                ItemName = "Computer",
                                Quantity = 1
                            },
                            new OrderItem()
                            {
                                OrderItemId = 206,
                                OrderId = 100,
                                ItemName = "Hard Drive",
                                Quantity = 2
                            }
                        }
                    },
                    new Order()
                    {
                        OrderId = 106,
                        CustomerId = 1,
                        OrderDate = DateTime.Now,
                        Shipped = true,
                        OrderItems = new List<OrderItem>()
                        {
                            new OrderItem()
                            {
                                OrderItemId = 207,
                                OrderId = 106,
                                ItemName = "Monitor",
                                Quantity = 3
                            },
                            new OrderItem()
                            {
                                OrderItemId = 208,
                                OrderId = 106,
                                ItemName = "DVD Burner",
                                Quantity = 2
                            }
                        }
                    }
                }
            },
            new Customer
            {
                CustomerId = 2,
                Name = "Arianna",
                Address = "456 Main Street",
                Orders = new List<Order>()
                {
                    new Order()
                    {
                        OrderId = 101,
                        CustomerId = 2,
                        OrderDate = DateTime.Now.AddDays(-10),
                        Shipped = true,
                        OrderItems = new List<OrderItem>()
                        {
                            new OrderItem()
                            {
                                OrderItemId = 201,
                                OrderId = 101,
                                ItemName = "barbie",
                                Quantity = 2
                            }
                        }
                    }
                }
            },
            new Customer
            {
                CustomerId = 3,
                Name = "Ryan",
                Address = "789 Main Street",
                Orders = new List<Order>()
                {
                    new Order()
                    {
                        OrderId = 102,
                        CustomerId = 3,
                        OrderDate = DateTime.Now.AddDays(-5),
                        Shipped = true,
                        OrderItems = new List<OrderItem>()
                        {
                            new OrderItem()
                            {
                                OrderItemId = 203,
                                OrderId = 103,
                                ItemName = "Minecraft",
                                Quantity = 2
                            }
                        }
                    }
                }
            }
        };
like image 480
adova Avatar asked Aug 25 '15 15:08

adova


People also ask

What is a query in C?

About the query The query we're going to run performs a basic search of the code for if statements that are redundant, in the sense that they have an empty then branch. For example, code such as: if (error) { }

Is SQL and C same?

So in summary, C is a language used to give commonly-understood commands to any arbitrary CPU while SQL is a language used to give commonly-understood commands to any arbitrary database back-end.

What is query function C++?

A query function is a mathematical expression evaluated against each item returned by a query, and whose output is stored in a dynamic, temporary field generated at query time.

Can you use SQL with C?

You can code SQL statements in a C or C++ program wherever you can use executable statements. Each SQL statement in a C or C++ program must begin with EXEC SQL and end with a semicolon (;). The EXEC and SQL keywords must appear on one line, but the remainder of the statement can appear on subsequent lines.


1 Answers

You're on the right path with

var customers2 = customers
    .Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)));

You just need an additional step as you can't filter the orders and the customers at the same time, you already filtered the customers to get only those you're interested in, now filter the orders themselves

var customers2 = customers
    .Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)))
    .Select(c => c.Orders.Where(o => o.OrderItems(o => o.OrderItems.Exists(oi => oi.Quantity == 1)));

This however leaves you with an ienumerable of ienumerable of orders, and not the customers, but you can't do exactly what you want (retrieve the customers and have their order property changed) as that would change their original order list, what you can do is create an Anonymous type to store both the orders and Customer in your query in the select as such:

var customers2 = customers
    .Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)))
    .Select(c => new
       {
       Customer = c,
       FilteredOrders =  c.Orders.Where(o => o.OrderItems(o => o.OrderItems.Exists(oi => oi.Quantity == 1))
       });

Now you can use this as such

foreach(var cust in customers2)
{
   cust.Customer // your original Customer object
   cust.Customer.Orders // your original orders collection for this Customer
   cust.FilteredOrders // only the orders you're interested in for this customer
}
like image 91
Ronan Thibaudau Avatar answered Nov 10 '22 02:11

Ronan Thibaudau