我试图优化以下简单实体框架查询retreieve所有的产品从同一组实体框架简单的子查询生成难看SQL
var query = from p in ctx.Products
where p.GroupId == (from q in ctx.Products
where q.Id == new Guid(".....")
select q.GroupId).FirstOrDefault()
select p;
检查使用SQL Server Profiler我看到这个生成的SQL后查询
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[GroupId] AS [GroupId],
[Extent1].[Name] AS [Name],
[Extent1].[Code] AS [Code]
FROM [inv].[Products] AS [Extent1]
LEFT OUTER JOIN (SELECT TOP (1) [Extent2].[GroupId] AS [GroupId]
FROM [inv].[Products] AS [Extent2]
WHERE cast('.....' as uniqueidentifier) = [Extent2].[Id]) AS [Limit1] ON 1 = 1
LEFT OUTER JOIN (SELECT TOP (1) [Extent3].[GroupId] AS [GroupId]
FROM [inv].[Products] AS [Extent3]
WHERE cast('.....' as uniqueidentifier) = [Extent3].[Id]) AS [Limit2] ON 1 = 1
LEFT OUTER JOIN (SELECT TOP (1) [Extent4].[GroupId] AS [GroupId]
FROM [inv].[Products] AS [Extent4]
WHERE cast('.....' as uniqueidentifier) = [Extent4].[Id]) AS [Limit3] ON 1 = 1
LEFT OUTER JOIN (SELECT TOP (1) [Extent5].[GroupId] AS [GroupId]
FROM [inv].[Products] AS [Extent5]
WHERE cast('.....' as uniqueidentifier) = [Extent5].[Id]) AS [Limit4] ON 1 = 1
LEFT OUTER JOIN (SELECT TOP (1) [Extent6].[Id] AS [Id]
FROM [inv].[Products] AS [Extent6]
WHERE cast('.....' as uniqueidentifier) = [Extent6].[Id]) AS [Limit5] ON 1 = 1
LEFT OUTER JOIN (SELECT TOP (1) [Extent7].[Id] AS [Id]
FROM [inv].[Products] AS [Extent7]
WHERE cast('.....' as uniqueidentifier) = [Extent7].[Id]) AS [Limit6] ON 1 = 1
WHERE ([Extent1].[GroupId] = (CASE WHEN ([Limit1].[GroupId] IS NULL)
THEN cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier)
ELSE [Limit2].[GroupId] END))
AND (CASE WHEN ([Limit3].[GroupId] IS NULL)
THEN cast('00000000-0000-0000-0000-000000000000' as uniqueidentifier)
ELSE [Limit4].[GroupId] END IS NOT NULL)
为什么它会生成这么多相同的JOIN? 有没有任何选项可以删除最终的空铸件? 你能否建议一些方法来改善生成的sql?
我还测试了LINQPad和一个正在生成普通的SQL
-- Region Parameters
DECLARE @p0 UniqueIdentifier = '....'
-- EndRegion
SELECT [t0].[Id], [t0].[GroupId], [t0].[Name], [t0].[Description], [t0].[Code]
FROM [inv].[Products] AS [t0]
WHERE [t0].[GroupId] = ((
SELECT TOP (1) [t1].[GroupId]
FROM [inv].[Products] AS [t1]
WHERE [t1].[Id] = @p0
))
如果你从你的应用程序获得不同的结果在LINQPad,请检查您使用的每个EF的版本并检查您的代码以确保在运行时没有任何内容被添加到表达式树中。 –
我正在使用EF 6.0,没有其他任何东西被添加到表达式树 –