【发布时间】: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