'GroupBy with many-to-many relationship in EFCore
Products:
+------+---------+--------------+
| id | name | status |
+------+---------+--------------+
| 1 | foo | in stock |
| 2 | bar | in stock |
| 3 | baz | out of stock |
+------+---------+--------------+
Items:
+------+---------+--------+
| id | name | Cost |
+------+---------+--------+
| 1 | item1 | 10 |
| 2 | item2 | 20 |
| 3 | item3 | 5 |
+------+---------+--------+
Intermediate table:
+--------------+------------+
| product_id | items_id |
+--------------+------------+
| 1 | 1 |
| 1 | 3 |
| 2 | 2 |
+--------------+------------+
Many to many configuration:
modelBuilder.Entity<Product>()
.HasMany<Item>(x => x.Items)
.WithMany(y => y.Products)
.UsingEntity(p => p.ToTable("ProductItems"));
Result should be:
{
'TotalItems': 3,
'Items': [
{ 'Status': 'in stock', 'Cost': 30 },
{ 'Status': 'out of stock', 'Cost': 5 }
]
}
Total count of items for a specific product:
context.Products
.Where(x => x.Name.Equals("foo"))
.SelectMany(x => x.Items)
.Count();
Now I want to group the items per product status. Something like:
context.Products
.Where(x => x.Name.Equals("foo"))
.SelectMany(x => x.Items)
.GroupBy(Status, (g,x) => new {
Status = ...
Cost = ...
})
.ToList()
Any ideas how to achieve the desired output?
Solution 1:[1]
you can create two dto like below and use groupby to do that
public class ItemDTO
{
public int Status { get; set; }
public decimal Cost { get; set; }
}
public class productDTO
{
public int TotalProducts { get; set; }
public int TotalItems { get; set; }
public List<ItemDTO> Items { get; set; }
}
then use this
var grouped = products.GroupBy(x => x.Status).Select(x =>new
{
key = x.Key,
value = x.ToList()
});
var res = new productDTO
{
TotalProducts = products.Count,
TotalItems = products.Sum(x => x.Items?.Count)??0,
Items = grouped.Select(x => new ItemDTO
{
Cost = x.value.Sum(q => q.Items?.Sum(i => i.Cost)??0),
Status = x.key
}).ToList()
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alifvar |
