【问题标题】:Grouping query fields from different tables (Entity Framework and ASP.NET Core)对来自不同表的查询字段进行分组(Entity Framework 和 ASP.NET Core)
【发布时间】:2022-01-10 01:50:21
【问题描述】:

我正在尝试将此查询转换为实体框架,但它不起作用。谁能明白为什么?

SELECT
    T3.COD1, T1.COD2,
    COUNT(T1.X1) R1 ,
    ROUND(SUM(T1.X2) / SUM(T2.X3),2) R2,
FROM 
    table1 A, table2 T2, table3 T3 
WHERE 
    T1.O_KEY = T3.O_KEY 
    AND T1.M_KEY = T2.M_KEY 
GROUP BY 
    T3.COD1, T1.COD2 
ORDER BY 
    T3.COD1, T1.COD2

其中 (WHERE T1.O_KEY = T3.O_KEY and T1.M_KEY = T2.M_KE) 指令等价于INNER JOIN

SELECT
    T3.COD1, T1.COD2,
    COUNT(T1.X1) R1 ,
    ROUND(SUM(T1.X2) / SUM(T2.X3),2) R2,
FROM 
    table1 A
INNER JOIN 
    table3 T3 ON T1.O_KEY = T3.O_KEY
INNER JOIN 
    table2 T2 ON T1.M_KEY = T2.M_KEY 
GROUP BY 
    T3.COD1, T1.COD2 
ORDER BY 
    T3.COD1, T1.COD2

转换:

//{Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1[App.Models.T1Model]}
var T1 =  _repositoryT1.GetAll(); // return context.T1
var T2 =  _repositoryT2.GetAll(); // return context.T2
var T3 =  _repositoryT3.GetAll(); // return context.T3

//注意:GetAll 方法不会将结果返回到内存。在 Dbset/LINK 上操作。T1、T2 和 T3 是数据库表。上下文类是实体框架的一个组成部分。 DbContext 的实例表示与数据库的会话,可用于查询实体实例并将其保存到数据库中

var query = 
(from xT1 in T1
 join xT3 in T3 on new { k1 = (long)xT1.O_KEY } equals new { k1 = (long)xT3.O_KEY }
 join xT2 in T2 on new { k1 = (long)xT1.M_KEY } equals new { k1 = (long)T2.M_KEY}
 group new { xT3, xT1 } by new { xT3.COD1 , xT1.COD2, xT1, xT3, xT2 } into G
 select new ResultDTO
 {
  COD1 = G.Key.COD1,
  COD2 = G.Key.COD2,
  R1 = T1.Count(),
  R2 = T1.Sum(x => (long)x.X2) / T2.Sum(x => (long)x.X2),
});

【问题讨论】:

  • EF Core 处理实体,而不是表。 LINQ 不是 SQL 替代品,它是一种由 EF Core 翻译为 SQL 的查询语言。使用 EF Core 的全部意义在于让 it 根据您的 entities 之间的关系而不是表之间的关系来编写 JOIN。否则,只需编写 SQL 查询并将结果映射到使用 Dapper 等对象。
  • 感谢@Panagiotis Kanavos。这个查询不是很复杂不应该可以转换吗?
  • 顺便说一句,SQL 中的连接方式在 30 年前就已经过时了,取而代之的是 JOIN。首先很难理解它的作用,而且像T1 这样的名称也无济于事。 T1是主表和T2、T3相关的吗?如果您使用 JOIN 重写查询,则 LINQ 查询将类似。 SQL 查询中没有 T2 字段,因此 LINQ 查询中也不应该有任何 T2 字段。不需要强制转换,事实上它们要么会导致错误,要么会导致查询效率低下。
  • shouldn't it be possible to convert? 是的,将其全部删除。如果您正确使用 EF Core,则可以删除所有这些代码。 dbContext.Orders.GroupBy(o=>o.Category.Name).Select(g=>new {Category=g.Key,Sum=g.Sum(o=>o.Total)} 正常工作,并生成 select c.Name as Category,SUM(Total) from Orders o INNER JOIN Categories c on o.CategoryId=c.ID GROUP BY c.Name。现在它比使用原始 SQL 更糟糕。无论如何,您的 LINQ 查询应该看起来像您的 SQL 查询,前提是您在 SQL 中也使用了 JOIN。 group 子句中没有强制转换,没有 T2 字段。
  • 谢谢大家。更新了查询以方便解释

标签: entity-framework asp.net-core


【解决方案1】:

我找到了答案。

var query = 
    (from xT1 in T1
     join xT3 in T3 on new { k1 = (long)xT1.O_KEY } equals new { k1 = (long)xT3.O_KEY }
     join xT2 in T2 on new { k1 = (long)xT1.M_KEY } equals new { k1 = (long)T2.M_KEY}
     select new { xT1, xT2, xT3 } into x
     group x by new { x.xT3.COD1 , x.xT1.COD2} into G
     select new ResultDTO
     {
      COD1 = G.Key.COD1,
      COD2 = G.Key.COD2,
      R1 = G.Count(),
      R2 = Convert.ToDecimal(G.Sum(x => (decimal)x.X2) / T2.Sum(x => (decimal)x.X2)),
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 2022-11-09
    • 1970-01-01
    • 2022-01-25
    • 2020-09-11
    相关资源
    最近更新 更多