简体   繁体   English

LINQ语句生成的查询与LinqPad不同

[英]LINQ statement generates different query than LinqPad

I have the following code that queries some data via a LEFT JOIN: 我有以下代码通过LEFT JOIN查询一些数据:

Model1 db = new Model1();

db.Database.Log = System.Console.Write;

var x = from e in db.Employees
        where e.id == 746
        join f in db.Company on e.CompanyID equals f.ID into fa
        from fr in fa.DefaultIfEmpty()
        select new
        {
          e.id,
          e.name,
          companyName = fr.name
        };

x.Any(); // to see the query in console

The classes used here are generated by Visual Studio Wizards to make sure that the model and DB context code is correct. 此处使用的类由Visual Studio向导生成,以确保模型和数据库上下文代码正确。

When i run that code in LINQpad the SQL query looks like 当我在LINQpad中运行该代码时,SQL查询看起来像

SELECT [t0].[id] AS [id], [t0].[name] AS [name], [t1].[name] AS [companyName]
FROM [Employees] AS [t0]
LEFT OUTER JOIN [Company] AS [t1] ON [t0].[CompanyID] = [t1].[ID]
WHERE [t0].[id] = 1615

But when i run the code in a simple Console Application i get the following cryptic query that is totally wrong: 但是,当我在一个简单的控制台应用程序中运行代码时,我得到以下完全错误的神秘查询:

SELECT 
    CASE WHEN ( EXISTS (SELECT 
        1 AS [C1]
        FROM  [dbo].[Employees] AS [Extent1]
        LEFT OUTER JOIN [dbo].[Company] AS [Extent2] ON ([Extent1].[CompanyID] = [Extent2].[ID]) OR (([Extent1].[CompanyID] IS NULL) AND ([Extent2].[ID] IS NULL))
        WHERE 1615 = [Extent1].[id]
    )) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]

I tried to find a solution for hours now and LINQ just doesnt get the query right. 我试图找到一个小时的解决方案,而LINQ却无法正确查询。

Did anybody have the same issue and solved it somehow? 有人遇到过同样的问题并以某种方式解决了吗? Any help is much appreciated. 任何帮助深表感谢。

This query looks correct to me. 这个查询对我来说看起来是正确的。 The LINQpad query looks different, because in your code you use Any() . LINQpad查询看起来有所不同,因为在您的代码中使用了Any()

Try the following query in LINQpad. 在LINQpad中尝试以下查询。 It should show the same sql: 它应该显示相同的SQL:

 (from e in Employees
    where e.id == 746
    join f in Company on e.CompanyID equals f.ID into fa
    from fr in fa.DefaultIfEmpty()
    select new
    {
      e.id,
      e.name,
      companyName = fr.name
    }).Any()

To see the correct query in your console, you could use ToList() instead of Any() 要在控制台中查看正确的查询,可以使用ToList()代替Any()

Obviously the two are using different underlying providers. 显然,两者使用的是不同的基础提供程序。 LinqPAD is treating x and x.Any() as two separate queries - it executes x in SQL and executes x.Any() in-memory. LinqPAD将xx.Any()视为两个单独的查询-它在SQL中执行x ,并在内存中执行x.Any()

Either the compiler or the provider your console app uses creates one IQueryable , so you end up with one SQL query. 您的控制台应用程序使用的编译器或提供程序都将创建一个IQueryable ,因此最终将产生一个SQL查询。 Note that you should be getting the right answer , but the combined SQL query removes items that are not necessary for Any like the field names you request. 请注意,您应该得到正确的答案 ,但是组合的SQL查询将删除“ Any所不需要的项目,例如您请求的字段名称。

If you did other things with x like convert it to a List or called AsEnumerable I'd bet you'd see roughly the same query from the console app. 如果您用x其他事情,例如将其转换为List或称为AsEnumerable我敢打赌,您会在控制台应用程序中看到大致相同的查询。

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

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