优化实体框架 Linq 查询(选择 1 个意外字段)

本文关键字:意外 字段 选择 实体 框架 Linq 查询 优化 | 更新日期: 2023-09-27 18:17:44

All,

谁能帮我优化以下EF/Linq查询:

EF/Linq 查询(取自 LinqPad(:

Articles
    .AsNoTracking()
    .Where(a => a.Active == "J")
    .SelectMany(a => KerlServices
        .Where(ks => ks.Service.SAPProductNumber == a.SAPProductNumber))
    .Select(ks => new {
        ks.KerlCode,
        ks.Service.SAPProductNumber,
        ks.Service.Type })
    .ToList()

文章和服务(ks.Service.SAPProductNumber == a.SAPProductNumber(之间的关系在理论上是1:可选的关系,不能在EF中定义。然而,这不是我的问题。

生成的 SQL 查询:

SELECT 
    [Join1].[F_SERVICESID] AS [F_SERVICESID], 
    [Join1].[F_KERLCOD] AS [F_KERLCOD], 
    [Join1].[F_SAPARTNUM] AS [F_SAPARTNUM], 
    [Join1].[F_TYPE] AS [F_TYPE]
    FROM  [dbo].[T_ART] AS [Extent1]
    INNER JOIN  (SELECT [Extent2].[F_KERLCOD] AS [F_KERLCOD], [Extent2].[F_SERVICESID] AS [F_SERVICESID], [Extent3].[F_SAPARTNUM] AS [F_SAPARTNUM], [Extent3].[F_TYPE] AS [F_TYPE]
        FROM  [dbo].[T_SERVICESKERL] AS [Extent2]
        INNER JOIN [dbo].[T_SERVICES] AS [Extent3] ON [Extent2].[F_SERVICESID] = [Extent3].[F_ID] ) AS [Join1] ON [Extent1].[F_SAPARTNUM] = [Join1].[F_SAPARTNUM]
    WHERE N'J' = [Extent1].[F_ACTIND]

为什么 EF 会生成选择 [Join1] 的查询。[F_SERVICESID]?我不需要这个字段。有谁知道防止这种情况的方法?

亲切的问候,一月。

加法1:

KerlServices
    .AsNoTracking()
    .Select(ks => new {
        ks.KerlCode,
        ks.Service.SAPProductNumber,
        ks.Service.Type })
    .Join(
        Articles,
        ks => ks.SAPProductNumber,
        a => a.SAPProductNumber,
        (ks, a) => new { ks, a.Active })
    .Where(ksa => ksa.Active == "J")
    .Select(ksa => ksa.ks)
    .ToList()

结果在:

SELECT 
    [Extent1].[F_SERVICESID] AS [F_SERVICESID], 
    [Extent1].[F_KERLCOD] AS [F_KERLCOD], 
    [Extent2].[F_SAPARTNUM] AS [F_SAPARTNUM], 
    [Extent2].[F_TYPE] AS [F_TYPE]
    FROM   [dbo].[T_SERVICESKERL] AS [Extent1]
    INNER JOIN [dbo].[T_SERVICES] AS [Extent2] ON [Extent1].[F_SERVICESID] = [Extent2].[F_ID]
    INNER JOIN [dbo].[T_ART] AS [Extent3] ON [Extent2].[F_SAPARTNUM] = [Extent3].[F_SAPARTNUM]
    WHERE N'J' = [Extent3].[F_ACTIND]

这种"改进"并没有回答我自己的问题,但结果对我来说肯定看起来更漂亮。

更新 1:

Ivan Stoev 答案中的查询生成以下 SQL:

SELECT 
    [Extent1].[F_SERVICESID] AS [F_SERVICESID], 
    [Extent1].[F_KERLCOD] AS [F_KERLCOD], 
    [Extent2].[F_SAPARTNUM] AS [F_SAPARTNUM], 
    [Extent2].[F_TYPE] AS [F_TYPE]
    FROM  [dbo].[T_SERVICESKERL] AS [Extent1]
    INNER JOIN [dbo].[T_SERVICES] AS [Extent2] ON [Extent1].[F_SERVICESID] = [Extent2].[F_ID]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[T_ART] AS [Extent3]
        WHERE (N'J' = [Extent3].[F_ACTIND]) AND ([Extent3].[F_SAPARTNUM] = [Extent2].[F_SAPARTNUM])
    )

优化实体框架 Linq 查询(选择 1 个意外字段)

为什么 EF 会生成选择 [Join1] 的查询。[F_SERVICESID]?我不需要这个字段。

如果这是真的,那就很奇怪了,我对此没有任何解释。

谁能帮我优化以下EF/Linq查询

值得尝试以下内容,对我来说,这代表了检索相关数据的最合乎逻辑的方法:

KerlServices
    .AsNoTracking()
    .Select(ks => new {
        ks.KerlCode,
        ks.Service.SAPProductNumber,
        ks.Service.Type })
    .Where(ks => Articles.Any(a => a.Active == "J" && a.SAPProductNumber == ks.SAPProductNumber)
    .ToList()

更新:最近我遇到EF在使用外键关系拨号时在生成的SQL查询中包含一些其他字段。这些字段不包括在预测结果中,因此我认为您不必担心。获取上面的任何查询,在实际代码环境(VS Debug(中执行它并检查投影列表 - 我很确定有问题的字段不会在那里。