为什么LINQ-to-Entities将此查询放在子选择中?

时间:2012-06-18 22:25:30

标签: c# linq linq-to-entities sybase

我有以下LINQ查询:

var queryGroups = (from p in db.cl_contact_event
                   select new Groups { inputFileName = p.input_file_name }).Distinct();

运行时会转换为以下内容:

SELECT 
[Distinct1].[C1] AS [C1], 
[Distinct1].[input_file_name] AS [input_file_name]
FROM ( SELECT DISTINCT 
       [Extent1].[input_file_name] AS [input_file_name], 
       1 AS [C1]
       FROM [mel].[cl_contact_event] AS [Extent1]
)  AS [Distinct1]

现在我非常肯定有一个子选择的原因是因为我有()包围的基本LINQ查询然后执行.Distinct()但我不太了解LINQ以确保这个。如果确实如此,那么有没有办法重构/编码我的查询,以便不会发生子选择?

我知道我似乎只是在这里采摘,但我只是好奇。

2 个答案:

答案 0 :(得分:4)

我根本不担心这种特殊情况。 SQL Server(很可能是任何企业数据库)无论如何都会优化掉外部的Select语句。我认为生成此SQL语句的原因是因为这是最通用和可重用的语句。根据我的经验,这总是发生在Distinct()

答案 1 :(得分:4)

在此我怀疑子查询的实际根本原因是匿名类型构造函数。因为您没有选择已知实体,而是选择从其他实体值构造的任意对象,所以EF解析器需要确保它可以生成确切的字段集 - 无论是来自单个表,连接表,计算字段,还是其他表达式树解析器非常善于尽可能地从LINQ查询中编写SQL语句,但它并不是无所不知的。它以系统的方式处理查询,始终产生正确的结果(从你得到你所要求的意义上),尽管并不总是最佳结果。

至于重写查询以消除子选择,首先关闭:我没有看到明显的方法来消除匿名类型并产生正确的结果。更重要的是,我 不会打扰 。像Sybase这样的现代SQL服务器非常智能 - 通常比开发人员更聪明 - 并且非常擅长从查询中生成最佳查询计划。除此之外,EF喜欢子查询,因为它们是以自动方式编写复杂查询的非常好的方法。即使您的LINQ查询没有出现使用它们,您也经常会找到它们。试图从你的查询中消除它们很快就会变得毫无用处。