简体   繁体   English

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

[英]optimize Entity Framework Linq query (selected 1 unexpected field)

All, 所有,

Can anyone help me optimize the following EF/Linq query: 谁能帮助我优化以下EF / Linq查询:

The EF/Linq query (taken from LinqPad): 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()

The relation between Articles and Services ( ks.Service.SAPProductNumber == a.SAPProductNumber ) is in theory a 1:optional relation with cannot be defined in EF. ks.Service.SAPProductNumber == a.SAPProductNumber与服务之间的关系( ks.Service.SAPProductNumber == a.SAPProductNumber )为1:可选关系,不能在EF中定义。 This is however not my question. 但是,这不是我的问题。

The resulting SQL query: 结果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]

Why does EF generate a query that selects [Join1].[F_SERVICESID]? EF为什么会生成一个选择[Join1]。[F_SERVICESID]的查询? I don't need this field. 我不需要这个领域。 Does anyone know a way to prevent this? 有谁知道防止这种情况的方法?

Kind regards, Jan. 亲切的问候,一月。

ADDITION 1: 附加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()

results in: 结果是:

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]

This 'improvement' does not answer my own question, but the result surely looks prettier to me. 这种“改进”并不能回答我自己的问题,但是结果肯定对我来说看起来更漂亮。

UPDATE 1: 更新1:

The query in Ivan Stoev's answer produces the following SQL: 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])
    )

Why does EF generate a query that selects [Join1].[F_SERVICESID]? EF为什么会生成一个选择[Join1]。[F_SERVICESID]的查询? I don't need this field. 我不需要这个领域。

That's weird if true, I have no explanation for that. 如果为真,那很奇怪,我对此没有任何解释。

Can anyone help me optimize the following EF/Linq query 谁能帮助我优化以下EF / Linq查询

It's worth trying the following, which for me represents the most logical way to retrieve the data in question: 值得尝试以下方法,对我而言,这是检索有问题的数据的最合逻辑的方法:

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()

UPDATE: Recently I've encountered that EF includes some additional fields in the generated SQL query when dialing with foreign key relations. 更新:最近我遇到了使用外键关系进行拨号时,EF在生成的SQL查询中包括一些其他字段的情况。 These fields are not included in the projected result, so I think you should not worry about. 这些字段包括在预计的结果中,因此我认为您不必担心。 Take any of the queries above, execute it inside the real code environment (VS Debug) and check the the projected list - I'm pretty sure the field in question will not be there. 接受上面的任何查询,在真实的代码环境(VS Debug)中执行它,并检查计划的列表-我很确定所讨论的字段将不存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM