实体框架对三个表进行分组和求和

问题描述 投票:0回答:3

我编写了一个 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”中不可用。

我也发现了非常类似的问题,但没有一个涵盖这个案例。

类似问题:

在 LINQ 中对多个表进行分组

此外,我尝试了以下方法:

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’”

c# asp.net sql-server entity-framework
3个回答
0
投票

您可以通过

DbSet.SqlQuery()
将工作 sql 查询直接传递到 EF 中,如下所述: https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbset.sqlquery?view=entity-framework-6.2.0


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 给我带来的结论。


0
投票

数据库模型和映射的类可以轻松高效地查询您想要的内容。

根据您自己答案中的代码,此 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
等)然后聚合要高效得多。

© www.soinside.com 2019 - 2024. All rights reserved.