我有这个EF模型:
n > 4
是否可以改善以下LINQ To Entities查询?
A computed property name in an interface must directly refer to a built-in symbol.
我担心将“ class Reception
{
public string Code { get; set; }
public virtual List<Row> { get; set; }
}
class Row
{
public string Item { get; set; }
public int Quantity { get; set; }
public float Weight { get; set; }
}
”部分做两次。
我不担心吗?
答案 0 :(得分:2)
如果基于GroupBy
,聚合查询(尤其是包含多个聚合的查询)最好转换为SQL,因为这是聚合的自然SQL构造。
因此,如果您想要更好的翻译并提高代码的可读性,则可以将相关查询转换为left outer join
+ group by
,如下所示:
var query = dbContext.Receptions
.SelectMany(r => r.Rows.DefaultIfEmpty(), (r, e) => new
{
r.Code,
Quantity = (int?)e.Quantity ?? 0,
Weight = (float?)e.Weight ?? 0,
})
.GroupBy(e => e.Code, (key, g) => new
{
code = key,
quantitySum = g.Sum(e => e.Quantity),
weightSum = g.Sum(e => e.Weight),
});
翻译成这样
SELECT
1 AS [C1],
[GroupBy1].[K1] AS [Code],
[GroupBy1].[A1] AS [C2],
CAST( [GroupBy1].[A2] AS real) AS [C3]
FROM ( SELECT
[Join1].[K1] AS [K1],
SUM([Join1].[A1]) AS [A1],
SUM([Join1].[A2]) AS [A2]
FROM ( SELECT
[Extent1].[Code] AS [K1],
CASE WHEN ([Extent2].[Quantity] IS NULL) THEN 0 ELSE [Extent2].[Quantity] END AS [A1],
CASE WHEN ([Extent2].[Weight] IS NULL) THEN cast(0 as real) ELSE [Extent2].[Weight] END AS [A2]
FROM [dbo].[Receptions] AS [Extent1]
LEFT OUTER JOIN [dbo].[Rows] AS [Extent2] ON [Extent1].[Code] = [Extent2].[Reception_Code]
) AS [Join1]
GROUP BY [K1]
) AS [GroupBy1]
对于此特定查询,这是从EF6可以获得的最好的结果。
答案 1 :(得分:0)
通常,EF也应使用数据库端的SUM函数将其转换为相当有效的数据库查询。但是如果您想确定的话,请使用SQL Server Profiler来分析查询。
我为您快速运行了这段代码,这就是EF的作用:
SELECT
[Project2].[Id] AS [Id],
[Project2].[Code] AS [Code],
[Project2].[C1] AS [C1],
CAST( [Project2].[C2] AS real) AS [C2]
FROM
(SELECT
[Project1].[Id] AS [Id],
[Project1].[Code] AS [Code],
[Project1].[C1] AS [C1],
(SELECT SUM([Extent3].[Weight]) AS [A1] FROM [dbo].[Rows] AS [Extent3] WHERE [Project1].[Id] = [Extent3].[Reception_Id]) AS [C2]
FROM
(SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Code] AS [Code],
(SELECT SUM([Extent2].[Quantity]) AS [A1] FROM [dbo].[Rows] AS [Extent2] WHERE [Extent1].[Id] = [Extent2].[Reception_Id]) AS [C1]
FROM
[dbo].[Receptions] AS [Extent1]
)AS [Project1]
)AS [Project2]
当然,我们可以编写更少子选择的更好的查询,但实际上,此查询不是SQL Server可以解决的问题。