转换" Linq查询到Sql查询"对我来说没有意义

时间:2017-05-02 16:29:11

标签: c# sql-server asp.net-mvc linq

我使用LinqPad 4将linq查询转换为sql。但是我对转换的sql查询非常困惑。我有一个与AppliedJob相关的工作表。 AppliedJob与JobOffer有关。 JobOffer与合同有关。合同表有一个字段CompletedDate,最初在作业合同开始时设置为Null。如果作业完成10,则使用当前日期更新该字段。我想得到那些有CompletedDate的工作清单!= Null(如果在Contract表中找到)。这意味着与合同相关的合同尚未完成或未在合同表中找到。未找到意味着任何合同不是从作业开始的。 我的林克:

     from j in Jobs 

  join jobContract in
                               (
                                   from appliedJob in AppliedJobs.DefaultIfEmpty()
                                   from offer in appliedJob.JobOffers.DefaultIfEmpty() 
                                   from contract in Contracts.DefaultIfEmpty()
                                   select new { appliedJob, offer, contract }
                                   ).DefaultIfEmpty()
                           on j.JobID equals jobContract.appliedJob.JobID into jobContracts
                           where jobContracts.Any(jobContract => jobContract.contract.CompletedDate != null)
                           select j.JobTitle

Linqpad做的我的Sql查询:

   SELECT [t0].[JobTitle]
FROM [Job] AS [t0]
WHERE EXISTS(
    SELECT NULL AS [EMPTY]
    FROM (
        SELECT NULL AS [EMPTY]
        ) AS [t1]
    LEFT OUTER JOIN ((
            SELECT NULL AS [EMPTY]
            ) AS [t2]
        LEFT OUTER JOIN ([AppliedJob] AS [t3]
            LEFT OUTER JOIN [JobOffer] AS [t4] ON [t4].[AppliedJobID] = [t3].[AppliedJobID]
            LEFT OUTER JOIN [Contract] AS [t5] ON 1=1 ) ON 1=1 ) ON 1=1 
    WHERE ([t5].[CompletedDate] IS NOT NULL) AND ([t0].[JobID] = [t3].[JobID])
    )

我的问题是,为什么它会在查询中生成这么多SELECT NULL AS [EMPTY]LEFT OUTER JOIN? 我能从中做出一个简单易懂的查询吗?或者可以吗?

3 个答案:

答案 0 :(得分:3)

DefaultIfEmpty()转换为左外连接。见LEFT OUTER JOIN in LINQ

有很多“NULL为[Empty]”因为NULL!= SQL中的NULL。请参阅为什么NULL = NULL evaluate to false in SQL server

答案 1 :(得分:0)

自从我触及C#和LINQ以来已经有一段时间了,但这是我的看法。

多个左外连接和空值的原因是因为您有几个(延迟?)调用DefaultIfEmpty()

没有双关语,但Enumerable.DefaultIfEmpty()默认返回值是多少?它是null。在您开始评估LINQ代码段中的连接条件之前,它们都会被评估和收集。

该代码片段代表方程式的非空右侧。整件事可以归还一套空白。

因此,兼容的SQL语句必须递归地在空集之间创建左外连接,直到实际的SQL连接标准。

这几乎是代数的。尝试了解LINQ和SQL语句都失效了。从头到尾一直向后工作到每个开头,你会看到等价。

答案 2 :(得分:0)

所有SELECT NULL AS [EMPTY]的原因是这些子查询没有用于返回数据,只是为了验证那里有数据。换句话说,LINQ代码正在优化查询,实际上不会引入任何列数据,因为这些子查询的目的完全没有必要。