我编写了一个 SQL 查询来获取每个汽车制造商的销售收入概览。
足够简单:
select
sum(s.Price * s.NumberOfCars) as Revenue, m.Name
from
Sale as s
join
Car as c on c.Id = s.CarId
join
Manufacturer as m on m.Id = c.ManufacturerId
group by
m.Name
返回以下输出:
有人知道如何使用实体框架来实现这一点吗?
我尝试过这个 Linq:
var salez = from s in _context.Sale
join c in _context.Car on s.CarId equals c.Id
join m in _context.Manufacturer on c.ManufacturerId equals m.Id
group m by m.Name into g
select new Manufacturer()
{
Name = g.Key,
Revenue = g.Sum(s => s.)
};
我无法计算总和,因为表“s”在组“g”中不可用。
我也发现了非常类似的问题,但没有一个涵盖这个案例。
类似问题:
此外,我尝试了以下方法:
SaleGroupManu = gret
.GroupBy(s => s.Car)
.Select(sc => new Car()
{
Umsatz = sc.Sum(s => s.Umsatz),
Manufacturer = sc.Key.Manufacturer
}).GroupBy(sc => sc.Manufacturer)
.Select(scm => new Manufacturer()
{
Name = scm.Key.Name,
Umsatz = scm.Sum(s => s.Umsatz)
}).ToList();
但我觉得它不是很优雅,因为我必须先按汽车分组,而使用 SQL,我可以直接按制造商分组。确实可行,但是还有更好的主意吗?
我尝试过原始sql,但它给了我错误,例如“‘FromSql’操作的结果中不存在所需的列‘Id’”
您可以通过
DbSet.SqlQuery()
将工作 sql 查询直接传递到 EF 中,如下所述:
https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbset.sqlquery?view=entity-framework-6.2.0
我最终用“!.”-我不知道的语法解决了这个问题。
SaleGroupManu = sale
.Include(s => s.Car)
.Include(s => s.Car!.Manufacturer).ToList()
.GroupBy(s => s.Car!.Manufacturer)
.Select(ms => new Manufacturer()
{
Name = ms.Key!.Name,
Revenue = ms.Sum(s => s.Revenue)
}).ToList();
应用程序更新:我再次远离实体......数据库迁移很舒服,但如果你使用太多,很容易让你的腿断掉。用于迁移的简单 sql 文件和用于查询的简洁文件更易于管理。另外,实体还始终使用“exec_sqlquery(...)”而不仅仅是查询本身。那也是……。这让我失望了。基本上是 Youtuber Tim Corey 给我带来的结论。
数据库模型和映射的类可以轻松高效地查询您想要的内容。
根据您自己答案中的代码,此 LINQ 查询应直接转换为 SQL,在查询中执行
GROUP BY
和聚合数据库端,看起来与您想要模拟的 SQL 查询非常相似:
_context.Sales
.GroupBy(s => s.Car.Manufacturer.Name)
.Select(grp => new Manufacturer()
{
Name = grp.Key,
Revenue = grp.Sum(s => s.Revenue)
}).ToList();
这比将所有数据拉入内存(使用
Include
等)然后聚合要高效得多。