提高LINQ To Entities查询(聚合)的性能

时间:2018-08-29 22:46:43

标签: entity-framework linq-to-entities

我有这个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; } } ”部分做两次。

我不担心吗?

2 个答案:

答案 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可以解决的问题。