简体   繁体   English

这两个LINQ查询之间有什么区别?

[英]What is the difference between these two LINQ queries?

Looking at the profiler I see a few differences. 看一下分析器,我看到了一些差异。 The second query which uses the include will in fact return data from related to the secondary table CountryCodes. 使用include的第二个查询实际上将返回与辅助表CountryCodes相关的数据。 This part makes sense to me. 这部分对我有意义。 I don't however understand why this query has two joins. 但是我不明白为什么这个查询有两个连接。 First it does a regular inner join between CountryCodes ands CountyCodeTypes (on the foreign key) which I would think be sufficient to return everything that the include requires. 首先,它在CountryCodes和CountyCodeTypes(在外键上)之间进行常规内连接,我认为这足以返回包含所需的所有内容。 However it then does another outer join. 然而,它然后做另一个外连接。 Why? 为什么?

var query = from codes in base.context.CountryCodes
            join codeTypes in base.context.CountryCodeTypes
            on codes.CountryCodeTypeId equals codeTypes.CountryCodeTypeId
            where codeTypes.CountryCodeTypeName == countryCodeType
            select codes;

var query = from codes in base.context.CountryCodes.Include("CountryCodeType")
            where codes.CountryCodeType.CountryCodeTypeName == countryCodeType
            select codes;

resulting sql: 结果sql:

 FROM   [dbo].[CountryCode] AS [Extent1]
 INNER JOIN [dbo].[CountryCodeType] AS [Extent2] ON [Extent1].[CountryCodeTypeId] = [Extent2].[CountryCodeTypeId]
 LEFT OUTER JOIN [dbo].[CountryCodeType] AS [Extent3] ON [Extent1].[CountryCodeTypeId] = [Extent3].[CountryCodeTypeId]
 WHERE [Extent2].[CountryCodeTypeName] = @p__linq__0

Also, is it fair to say that I should use the .Include only when I actually need data in the foreign key table to be populated in my result, otherwise use the join? 另外,如果我实际上需要在我的结果中填充外键表中的数据,我应该使用.Include,否则使用连接? In other words I shouldn't use the .Include as the means to the join because the navigational properties know how to join entities for me based on the keys. 换句话说,我不应该使用.Include作为连接的手段,因为导航属性知道如何根据键为我加入实体。

This is just the nature of Entity Framework generated SQL. 这只是Entity Framework生成的SQL的本质。

The INNER JOIN exists because of your where statement. INNER JOIN因您的where语句而存在。

where codes.CountryCodeType.CountryCodeTypeName == countryCodeType

The only way EF can resolve this is to perform an INNER JOIN, as you correctly point out. EF可以解决此问题的唯一方法是执行INNER JOIN,正如您正确指出的那样。 You are also correct in noting that the INNER JOIN does in fact return all the data required to satisfy the Include() . 你也注意到INNER JOIN确实返回了满足Include()所需的所有数据。

However the OUTER JOIN is still executed, simply because EF sees an Include() and parses that as requiring the join. 但是,OUTER JOIN仍然执行,因为EF看到Include()并将其解析为需要连接。 Consider the case where you don't have a where clause - you'd need an OUTER JOIN then, right? 考虑一下你没有where子句的情况 - 那么你需要一个OUTER JOIN,对吗? Well EF isn't smart enough to determine that the OUTER JOIN isn't required in this case; 在这种情况下,EF不够聪明,无法确定是否需要OUTER JOIN; it sees an Include() and then generates the relevant OUTER JOIN to ensure that the data requirements will be satisfied. 它看到一个Include()然后生成相关的OUTER JOIN以确保满足数据要求。 In other words, it isn't considering the rest of your query to determine whether the join is required - it just does it regardless. 换句话说,它不会考虑您的其余查询来确定是否需要连接 - 它只是无论如何都可以。

Regarding the Include() operator, you would only use it when you want to retrieve those related objects back to your application. 关于Include()运算符,只有在想要将这些相关对象检索回应用程序时才会使用它。 It's not required for this query. 此查询不需要它。 The simplest query in this case would be 在这种情况下最简单的查询是

var query = from codes in base.context.CountryCodes
            where codes.CountryCodeType.CountryCodeTypeName == countryCodeType
            select codes;

The left outer join happens as a result of the codes.CountryCodeType.CountryCodeTypeName == countryCodeType , whereas the inner join happens to allow it to include fields from the CountryCodeType table in the final results. 由于codes.CountryCodeType.CountryCodeTypeName == countryCodeType ,左外连接发生,而内连接恰好允许它在最终结果中包含CountryCodeType表中的字段。

If you don't need the data from the foreign key table in your result, you don't need to use Include or Join. 如果您不需要结果中的外键表中的数据,则无需使用“包括” 或“加入”。 If you didn't use "Include", it would only use the left outer join, and not the inner join. 如果您没有使用“Include”,它将只使用左外连接,而不使用内连接。

I'm guessing the framework simply isn't smart enough to realize that it's already done a join on that table, and can reuse the information there. 我猜这个框架根本不够智能,没有意识到它已经在该表上完成了连接,并且可以在那里重用信息。 Hopefully SQL Server is smart enough to pick up on that and use an execution plan that avoids duplicating that effort. 希望SQL Server足够聪明,可以接受并使用执行计划,避免重复这种努力。

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

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