views:

153

answers:

3

How to use Linq to select and group complex child object from a parents list.

I have an OrderList each of order object has a OrderProductVariantList(OrderLineList), and each of OrderProductVariant object has ProductVariant, and then the ProductVariant object will have a Product object which contains product information.

My goal is to select and group the most popular products from the order list.

Can anyone help me with this?

Many thanks.

+2  A: 

Your description is hard to follow, but I think you just want to get out the Products and rank them by the number of times they occur. SelectMany will be helpful for this.

 var query = orderList.SelectMany( o => o.OrderLineList )
                        // results in IEnumerable<OrderProductVariant>
                      .Select( opv => opv.ProductVariant )
                      .Select( pv => p.Product )
                      .GroupBy( p => p )
                      .Select( g => new {
                                    Product = g.Key,
                                    Count = g.Count()
                       });
tvanfosson
Try breaking it down into each component of the query. And see what each one gives you, e.g. `var q = orderList.SelectMany();` then `var q1 = q.Select(...)`, etc. I'm not sure why it wouldn't show up in the debugger -- are you looking at the local variables?
tvanfosson
HI tvanfosson, thank you very much. The Linq is really good tool. I have managed to get the result. Here is another question, in the OrderProductVariant(orderLine) object I have the Quantity and UnitPrice properties, if also want to bring them into the report how can I do that?
Daoming Yang
Instead of selecting just the project, select a new anonymous type that includes the Product, Quantity, and UnitPrice. You'll have to use all three as the key for grouping -- again, use an anonymous object for this, then select each out a g.Key.Product, g.Key.Quantity, ...
tvanfosson
+1  A: 

A query is not a result. To view the result you can iterate over the query object:

foreach (var result in query) {
    Console.WriteLine(result);
} 

As to why query wasn't available in the watch window, I can only imagine that it either wasn't in scope yet, or it had already gone out of scope. Try putting a breakpoint on the line immediately after the line you posted where you assign to query.

Mark Byers
Hmm.. the question is now completely different from when I posted this answer. The original question was something like `For this query: "var query = orderList.SelectMany(...blah" why is there no result, and why does it say "query is not defined" in the watch window?`
Mark Byers
Hi Mark, I do not why the data not showing in the watch window, but it can bring the result out, very strange.
Daoming Yang
A: 

Hi tvanfosson, I'm doing this by following your suggestion, but I can I select and group them? I only can get the Product detail. Could you help?

var itemstest = productList.SelectMany(o => o.OrderProductVariantList.OfType<OrderProductVariant>())
                .Select(opv => new { 
                    ProductVariant = opv.ProductVariant.Product,
                    Quanity = opv.Quantity,
                    UnitPrice = opv.PriceSales
                })
                .Select(pv => pv.ProductVariant.Product)
                .GroupBy(p => p)
                .Select(g => new ProductReport
                {
                    Product = g.Key,
                    TotalOrderCount = g.Count()
                })
                .OrderByDescending(x => x.TotalOrderCount).ToList();
Daoming Yang