简体   繁体   中英

How to show name of company with orders in query?

I am trying to get the name of the company to show on top of each group that contains OrderDate and the Total made, for example:

Ray's Company

11/1/1996 12:00:00 AM

2296.00

Jay's Company

3/10/1997 12:00:00 AM

956.68

Bee's Company

11/13/1997 12:00:00 AM

1416.00

I have only been able to show the OrderDate and Total, but not the company's name. Would like to know how I could show the company's name as well. Here is what I have thus far:

static void Exercise21()
    {
        List<Customer> customers = DataLoader.LoadCustomers();

        var companys = (from y in customers
                       group y by y.CompanyName into newCompany
                       select newCompany).ToList(); //this is company name

        var customersSort = (from customer in customers
                             from x in customer.Orders
                            group x by x.OrderDate into newGroup
                            select newGroup).ToList();

        string line = "{0,-35}";
        Console.WriteLine(line, "Category");
        Console.WriteLine("======================================================================================");

        foreach (var customerGroup in customersSort)
        {
            Console.WriteLine();
            Console.WriteLine(customerGroup.Key);

            foreach (var customer in customerGroup)
            {
                Console.WriteLine(line, customer.Total);
            }
        }
    }

To address your question and consideration, the company name needs to output in the iteration. You can handle this by ensuring you are handling your grouping in the context of iterating through the List<Customer> sequence. This can be done in the foreach-loop or in the expression (referenced to as the alternative in this answer.

So, there are a couple implementations you can do here but reflect the same notion: grouping in the context of iterating.

In the following one I'm going to represent handling the lambda linq expressions in the context of iterating with the foreach-loop on List<Customer> Customers .

Type definitions and DataLoader.LoadCustomers() Mock

public class Customer
{
    public string CompanyName { get; set; }
    public IEnumerable<Order> Orders { get; set; }
}

public class Order
{
    public DateTime OrderDate { get; set; }
    public double Total { get; set; }
}

static IEnumerable<Customer> GetCustomersMocks()
{
    return new List<Customer>
    {
        new Customer
        {
             CompanyName = "Ray's Company",
             Orders = new List<Order>
             {
                 new Order { OrderDate = DateTime.Parse("11/1/1996 12:00:00 AM"), Total = 1148},
                 new Order { OrderDate = DateTime.Parse("11/1/1996 12:00:00 AM"), Total = 1148}
             }
        },
        new Customer
        {
             CompanyName = "Jay's Company",

             Orders = new List<Order>
             {
                 new Order { OrderDate = DateTime.Parse("3/10/1997 12:00:00 AM"), Total = 478.34 },
                 new Order { OrderDate = DateTime.Parse("3/10/1997 12:00:00 AM"), Total = 478.34 }
             }
        },
        new Customer
        {
             CompanyName = "Bee's Company",
             Orders = new List<Order>
             {
                 new Order { OrderDate = DateTime.Parse("11/13/1997 12:00:00 AM"), Total = 708 },
                 new Order { OrderDate = DateTime.Parse("11/13/1997 12:00:00 AM"), Total = 708 }
             }
        }
    };
}

Sample

static void Exercise21()
{
    //List<Customer> customers = DataLoader.LoadCustomers();

    var customers = GetCustomersMocks();

    string line = "{0,-35}";
    Console.WriteLine(line, "Category");
    Console.WriteLine("======================================================================================");

    foreach (var customer in customers)
    {
        Console.WriteLine();
        Console.WriteLine(customer.CompanyName);
        var groupedOrdersList = (from c in customer.Orders group c by c.OrderDate);
        foreach (var groupedOrders in groupedOrdersList)
        {
            Console.WriteLine(groupedOrders.Key);
            Console.WriteLine(line, (from g in groupedOrders select g.Total).Sum());
        }
    }
}

Console Output

控制台输出


Here is an alternative that uses .SelectMany and GroupBy .

var groupedCustomerByCompanyNameOrderDate = customers.SelectMany(c => c.Orders.Select(o => new { c.CompanyName, o.OrderDate, o.Total }))
    .GroupBy(c => new { c.CompanyName, c.OrderDate });

foreach (var g in groupedCustomerByCompanyNameOrderDate)
{
    Console.WriteLine();
    Console.WriteLine(g.Key.CompanyName);
    Console.WriteLine(g.Key.OrderDate);
    Console.WriteLine(g.Sum(o => o.Total));
}

In the code above, your selecting (projecting to) an anonymous type and flattening the IEnumerable<IEnumerable<T>> Result to IEnumerable<T> (though it is deferred execution). You then perform a GroupBy on that sequence and iterate with one foreach loop (without nesting another foreach loop).

see Enumerable.SelectMany documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM