作为学习 EF
的练习,我有以下 4 个表格。 Person 1toM
,订单 M2M
,通过 OrderProducts 获取产品
(性别是一个 Enum
>):
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Gender Gender { get; set; }
public IList<Order> Orders { get; set; }
}
public class Order
{
public int Id { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
public IList<OrderProduct> OrderProducts { get; set; }
}
public class OrderProduct
{
public int Id { get; set; }
public int Qty { get; set; }
public Order Order { get; set; }
public int OrderId { get; set; }
public Product Product { get; set; }
public int ProductId { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public IList<OrderProduct> OrderProducts { get; set; }
}
我正在尝试使用 LINQ 扩展方法生成以下内容:
A list of products and total
[=Sum(OrderProducts.Qty * Product.Price)]
spent, grouped by product name then grouped by gender.
结果看起来像这样:
Female
Ball $655.60
Bat $1,925.40
Glasses $518.31
Etc...
Male
Ball $1,892.30
Bat $3,947.07
Glasses $1,315.71
Etc...
我致力于LINQ扩展方法,并希望我也能在这里开发一些最佳实践。我现在不知道如何按 ProductName
分组并将 Qty * Price
按产品汇总为总计:
var prodsalesbygender = context.Orders
.GroupBy(o => new
{
Gender = o.Person.Gender
})
.Select(g => new
{
ProductName = g.Select(o => o.OrderProducts.Select(op => op.Product.Name)),
Qty = g.Select(o => o.OrderProducts.Select(op => op.Qty)),
Price = g.Select(o => o.OrderProducts.Select(op => op.Product.Price))
}
);
我尝试将 .GroupBy(g => g.ProductName)
添加到末尾,但收到错误“调用“GroupBy”方法的关键选择器类型为在底层商店提供商中不具有可比性。”。
最佳答案
我想你已经快到了.. 试试这个:
var prodsalesbygender = context.Orders
.GroupBy(o => new
{
Gender = o.Person.Gender
})
.Select(g => new
{
Gender = g.Key,
Products = g.Select(o => o.OrderProducts
.GroupBy(op => op.Product)
.Select(op => new
{
ProductName = op.Key.Name,
Qty = op.Sum(op2 => op2.Qty),
Price = op.Select(x => x.Product.Price)
.First(),
})
.Select(x => new
{
ProducName = x.ProductName,
Qty = x.Qty,
Price = x.Price,
TotalPrice = x.Qty * x.Price
}))
});
简而言之,你只需要更多的投影。在我建议的解决方案中,首先按性别分组。下一步是直接投影性别和“产品列表”(是的,最难解决的部分是 OrderProducts
)。在Products
中,我们按产品名称对其进行分组,然后获取总数量(Qty
)并设置价格
- 假设价格相同产品是恒定的。下一步是设置 TotalPrice
,即 Qty * Price
内容。
诗。我充分意识到这个查询有很多缺陷。也许LINQ专家可以在这方面提供更好的帮助。
这将产生一个类似于以下内容的类:
{
Gender Gender
IEnumerable<{ ProductName, Qty, Price, TotalPrice }> Products
}
是的,匿名类型就这么多了..
尽管如此,我对否决票感到困惑,因为问题包含有问题的模型和 OP 提供的尝试。
关于c# - 具有多个 GroupBy 要求的多重联接的 LINQ 扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46965897/