views:

118

answers:

1

Hi

how can you do multiple "group by's" in linq to sql?

Can you please show me in both linq query syntax and linq method syntax.

Thanks

Edit.

I am talking about multiple parameters say grouping by "sex" and "age".

Also I forgot to mention how would I say add up all the ages before I group them.

If i had this example how would I do this

Table Product

ProductId ProductName ProductQty ProductPrice

Now imagine for whatever reason I had tons of rows each with the same ProductName, different ProductQty and ProductPrice.

How would I groupt hem up by Product Name and add together ProductQty and ProductPrice?

I know in this example it probably makes no sense why there would row after row with the same product name but in my database it makes sense(it is not products).

+3  A: 

To group by multiple properties, you need to create a new object to group by:

var groupedResult = from person in db.People
                    group by new { person.Sex, person.Age } into personGroup
                    select new 
                    { 
                        personGroup.Key.Sex, 
                        personGroup.Key.Age, 
                        NumberInGroup = personGroup.Count() 
                    }

Apologies, I didn't see your final edit. I may be misunderstanding, but if you sum the age, you can't group by it. You could group by sex, sum or average the age...but you couldn't group by sex and summed age at the same time in a single statement. It might be possible to use a nested LINQ query to get the summed or average age for any given sex...bit more complex though.

EDIT:

To solve your specific problem, it should be pretty simple and straightforward. You are grouping only by name, so the rest is elementary (example updated with service and concrete dto type):

class ProductInventoryInfo
{
    public string Name { get; set; }
    public decimal Total { get; set; }
} 

class ProductService: IProductService
{

    public IList<ProductInventoryInfo> GetProductInventory()
    {
        // ...

        var groupedResult = from product in db.Products
                            group by product.ProductName into productGroup
                            select new ProductInventoryInfo
                            {
                                Name = productGroup.Key,
                                Total = productGroup.Sum(p => p.ProductCost * p.ProductQty)
                            }

        return groupedResult.ToList();
    }
}
jrista
I can do it in 2 statements as long as the end result is I have a field that is totaled.
chobo2
Are you looking for the sum of age, or the average age, per sex?
jrista
well I am looking for sums actually for both(sex and age examples but in my real db I am adding 2 tables up).
chobo2
I put a example of sort what I want to do.
chobo2
your statement is summing up both the product cost and qty together? or will they be 2 different fields in the end?
chobo2
what does this return anyways this statement? I am not sure what it returns so I don't know what to return from my method.
chobo2
This returns an object with two properties, Name and Total. Total is the summation of ProductCost times ProductQuantity, which would effectively reflect the base value of inventory grouped by product. I am not sure if that is what you are after, but thats what it does.
jrista
Oops, noticed I added Cost and Qty rather than multiplied. I fixed it.
jrista
*What is "groupedResult" I have it in a repository and I want to return it to my service layer(I don't want to do business logic in my repository). I don't know what to return though.
chobo2
I updated my example to demonstrate what groupedResult is. It is an anonymous type with two properties, string Name and decimal Total (I am assuming ProductCost is a decimal.) If you wish to return it from a service, then you would need to create an actual concrete type, and new that up in the select statement: select new ProductInventoryResult { ... }.
jrista
You are correct that ProductCost would be a decimal. I want to return it from a repository to service. I don't follow you with making a new select statement.Do you mean I have to make a new class with the properties? Then add it to that?
chobo2
I have updated the example again to demonstrate my last comment. Sorry for the ambiguity.
jrista