简体   繁体   English

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

[英]Why does LINQ-to-Entities put this query in a sub-select?

I have the following LINQ query: 我有以下LINQ查询:

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

Which translates to the following when run: 运行时转换为以下内容:

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]

Now I'm pretty sure that the reason there is a sub-select is because I have the base LINQ query surrounded by () and then perform .Distinct() but I don't know enough about LINQ to be sure of this. 现在我很确定有一个子选择的原因是因为我有()包围的基本LINQ查询然后执行.Distinct()但我不太了解LINQ以确保这一点。 If that's indeed the case is there a way to restructure/code my query so that a sub-select doesn't occur? 如果确实如此,那么有一种方法可以重构/编码我的查询,以便不会发生子选择吗?

I know that it probably seems that I'm just nit-picking here but I'm just curious. 我知道这似乎我只是在这里挑选,但我只是好奇。

I wouldn't worry about this particular situation at all. 我根本不担心这种特殊情况。 SQL Server (and most likely any enterprise database) will optimize away the outer Select statement anyway. SQL Server(很可能是任何企业数据库)无论如何都会优化掉外部的Select语句。 I would theorize that the reason this SQL statement is generated is because this is the most generic and reusable statement. 我认为生成此SQL语句的原因是因为这是最通用和可重用的语句。 From my experience, this always happens on Distinct() . 根据我的经验,这总是发生在Distinct()

In this I suspect that the actual root cause of the subquery is the anonymous type constructor. 在此我怀疑子查询的实际根本原因是匿名类型构造函数。 Because you are not selecting a known entity, but rather an arbitrary object constructed from other entity values, the EF parser needs to make sure it can produce the exact set of fields -- whether from a single table, joined tables, calculated fields, other sub-queries, etc. The expression tree parser is very good at writing SQL statements out of LINQ queries whenever possible, but it's not omniscient. 因为您没有选择已知实体,而是选择从其他实体值构造的任意对象,所以EF解析器需要确保它可以生成确切的字段集 - 无论是来自单个表,连接表,计算字段,还是其他表达式树解析器非常善于尽可能地从LINQ查询中编写SQL语句,但它并不是无所不知的。 It processes the queries in a systematic way, that will always produce correct results (in the sense that you get what you asked for), though not always optimal results. 它以系统的方式处理查询,始终产生正确的结果(从你得到你所要求的意义上),尽管并不总是最佳结果。

As far as rewriting the query to eliminate the sub-select, first off: I don't see an obvious way to do so that eliminates the anonymous type and produces correct results. 至于重写查询以消除子选择,首先关闭:我没有看到一种明显的方法来消除匿名类型并产生正确的结果。 More importantly, though, I wouldn't bother . 更重要的是,我不会打扰 Modern SQL servers like Sybase are very smart -- often smarter than the developer -- and very good at producing an optimal query plan out of a query. 像Sybase这样的现代SQL服务器非常智能 - 通常比开发人员更聪明 - 并且非常擅长从查询中生成最佳查询计划。 Besides that, EF loves sub-queries, because they are very good ways to write complex queries in an automated fashion. 除此之外,EF喜欢子查询,因为它们是以自动方式编写复杂查询的非常好的方法。 You often find them even when your LINQ query did not appear use them. 即使您的LINQ查询没有出现使用它们,您也经常会找到它们。 Trying to eliminate them all from your queries will quickly become an exercise in futility. 试图从你的查询中消除它们很快就会变得徒劳无功。

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

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