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

Kit*_*124 7 c# linq sybase linq-to-entities

我有以下LINQ查询:

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

运行时转换为以下内容:

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]
Run Code Online (Sandbox Code Playgroud)

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

我知道这似乎我只是在这里挑选,但我只是好奇.

Mic*_*eld 4

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

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