我有以下代码通过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
此处使用的类由Visual Studio向导生成,以确保模型和数据库上下文代码正确。
当我在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
但是当我在一个简单的控制台应用程序中运行代码时,我得到以下完全错误的神秘查询:
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]
我试图找到一个解决方案现在几个小时,LINQ只是没有得到正确的查询。
有人有同样的问题并以某种方式解决了吗?非常感谢任何帮助。
答案 0 :(得分:4)
此查询对我来说是正确的。 LINQpad查询看起来不同,因为在您的代码中使用Any()
。
在LINQpad中尝试以下查询。它应该显示相同的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()
要在控制台中查看正确的查询,您可以使用ToList()
代替Any()
答案 1 :(得分:1)
显然,这两个使用不同的底层提供商。 LinqPAD将x
和x.Any()
视为两个单独的查询 - 它在SQL中执行x
并在内存中执行x.Any()
。
您的控制台应用程序使用的编译器或提供程序会创建一个IQueryable
,因此您最终会得到一个SQL查询。请注意,您应该获得正确的答案,但组合的SQL查询会删除Any
不需要的项目,例如您请求的字段名称。
如果您使用x
进行其他内容,例如将其转换为List
或称为AsEnumerable
,我打赌您会看到大致相同的查询来自控制台应用程序。