2015-10-15 92 views
0

所有,优化实体框架的LINQ查询(选择1意外场)

谁能帮我优化下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:

伊万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]) 
    ) 
+0

我正在用尽想法。 EF版本?数据库类型 - Sql Server?你有没有检查它在VS而不是LinqPad? –

+0

@IvanStoev:好主意看看不使用LinqPad时生成的SQL。也许LinqPad是负责任的。 –

+0

查看我更新的答案。在处理另一个SO问题时,我发现了类似的情况,并且从查询实现的角度来看完全没有问题。 –

回答

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)中执行它并检查投影列表 - 我很确定相关字段不会在那里。

+0

感谢您的回答。非常酷,你实际上提到了我开始优化之前的* exact *查询。我将那个生成的SQL作为** UPDATE 1 **添加到了我原来的问题中。 –

+0

@ JanC.deGraaf Sql查询看起来完全是我将手写的,除了别名和那个奇怪的列。所以无论我们做什么,你都会得到这个'[F_SERVICEID]'。顺便说一下,KerlCode属性的类型是什么? –

+0

“KerlCode”属性的类型是必需的 - 字符串长度-5。在数据库中它是'nvarchar(5),不是空'。 –