如何在dotnet core Entity Framework中对多个表的数据进行GroupBy操作?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在dotnet core Entity Framework中对多个表的数据进行GroupBy操作?相关的知识,希望对你有一定的参考价值。
我正在构建一些市场的web应用,比方说像e-bay这样的东西。典型的场景是:用户提出一个或多个物品的报价,这些物品是某种类型的。
用户出价,其中包括一个或多个项目,这些项目是特定的类型,然后其他用户对该报价进行竞价。
这里是简化的图。
在SQL Fiddle (此处)你可以看到CREATE TABLE和INSERT INTO两个语句。
样本数据。有两个报价。其中一个报价(Id 1)包含一件商品,类型为 "手表"。另一个报价(Id 2),其中有一件物品是 "耳机"。两个报价都有出价。在手表上,有两个人出价,一个人出价100美元,另一个人出价120美元。在耳机上,有50美元和80美元的出价。
我想实现的是每一种类型的平均出价。在这个样本中,这意味着我想让手表的平均出价为110美元,耳机的平均出价为65美元。为了达到这个目的,使用T-SQL,我会写这样的查询。
SELECT t.name,
avg(amount)
FROM bid b
LEFT JOIN offer o ON b.OfferId = o.id
LEFT JOIN offeritem oi ON o.id = oi.OfferId
LEFT JOIN itemType t ON oi.itemtypeid = t.Id
GROUP BY t.name
所以,我的问题是,如何在dotnet core 3. 0 EntityFramework中实现这个目标?
使用GroupBy,像这样。
_context.Bids
.Include(b => b.Offer)
.ThenInclude(o => o.OfferItems)
.ThenInclude(os => os.ItemType)
.GroupBy(b => b.Offer.OfferItems.First().ItemType.Name);
就会产生异常
客户端不支持GroupBy。
. 当我尝试使用投影,像这样。
_context.Bids
.Include(b => b.Offer)
.ThenInclude(o => o.OfferItems)
.ThenInclude(os => os.ItemType)
.GroupBy(b => b.Offer.OfferItems.First().ItemType.Name)
.Select(g => new
{
Key = g,
Value = g.Average(b => b.Amount)
});
我又得到异常:
处理LINQ......失败。这可能表明EF Core的一个错误或限制。
EDIT:
这种方法
_context.Bids
.Include(b => b.Offer)
.ThenInclude(o => o.OfferItems)
.ThenInclude(os => os.ItemType)
.GroupBy(b => new { b.Offer.OfferItems.First().ItemType.Name}, b => b.Amount)
.Select(g => new
{
Key = g.Key.Code,
Value = g.Average()
});
也抛出了一个异常,但这次。
不能在GROUP BY子句的group by list表达式中使用集合或子查询。
...
那么,有没有一种方法可以对数据进行分组(得到简单的Average),或者我应该再做一个查询,然后自己遍历集合并进行计算?这肯定会降低性能(我希望我可以做服务器分组,但正如你所看到的,我遇到了上述问题)。有什么想法吗?先谢谢你了。
在你的案例中,很难隐藏分组中的子查询。
你可以试试这样的方式
var joined =
context.Bid
.SelectMany(x =>
x.Offer.OfferItem
.Select(y => new
{
Amount = x.Amount,
Name = y.ItemType.Name
})
.Take(1));
var grouped = from i in joined
group i by i.Name into groups
select new
{
Key = groups.Key,
Amount = groups.Average(x => x.Amount)
};
它给我一个查询
SELECT [t].[Name] AS [Key], AVG([t].[Amount]) AS [Amount]
FROM [Bid] AS [b]
INNER JOIN [Offer] AS [o] ON [b].[OfferId] = [o].[Id]
CROSS APPLY (
SELECT TOP(1) [b].[Amount], [i].[Name], [o0].[Id], [i].[Id] AS [Id0], [o0].[OfferId]
FROM [OfferItem] AS [o0]
INNER JOIN [ItemType] AS [i] ON [o0].[ItemTypeId] = [i].[Id]
WHERE [o].[Id] = [o0].[OfferId]
) AS [t]
GROUP BY [t].[Name]
以上是关于如何在dotnet core Entity Framework中对多个表的数据进行GroupBy操作?的主要内容,如果未能解决你的问题,请参考以下文章
Linux 上的 C# DotNet Entity Framework Core Migrations 错误
dotnet跨平台微软昨天宣布正式发布.NET Core RC2和.NET Core SDK Preview 1,还有Entity Framework Core RC2
我可以将 Entity Framework Core 6 与 Windows 窗体一起使用(使用 .NET 5)吗?
如何在 dotnet core 中制作自定义身份验证过滤器,如 Iauthentication