C# 如何在实体框架中编写此SQL查询?

C# 如何在实体框架中编写此SQL查询?,c#,sql-server,sql-server-2008,entity-framework,C#,Sql Server,Sql Server 2008,Entity Framework,我有一个查询,我想把它从实体框架转换成SQL,几乎是1:1: SELECT GroupId, ItemId, count(*) as total FROM [TESTDB].[dbo].[TestTable] WHERE GroupId = '64025' GROUP BY GroupId, ItemId ORDER BY GroupId, total DESC 此SQL查询应根据相同ItemId(针对该组)的出现次数进行排序 我现在有: from x in dataConte

我有一个查询,我想把它从实体框架转换成SQL,几乎是1:1:

SELECT GroupId, ItemId, count(*) as total
  FROM [TESTDB].[dbo].[TestTable]
  WHERE GroupId = '64025'
  GROUP BY GroupId, ItemId
  ORDER BY GroupId, total DESC
此SQL查询应根据相同
ItemId
(针对该组)的出现次数进行排序

我现在有:

from x in dataContext.TestTable.AsNoTracking()
where x.GroupId = 64025
group x by new {x.GroupId, x.ItemId}
into g
orderby g.Key.GroupId, g.Count() descending 
select new {g.Key.GroupId, g.Key.ItemId, Count = g.Count()};
但这会生成以下SQL代码:

SELECT 
  [GroupBy1].[K1] AS [GroupId], 
  [GroupBy1].[K2] AS [ItemId], 
  [GroupBy1].[A2] AS [C1]
FROM ( SELECT 
         [Extent1].[GroupId] AS [K1], 
         [Extent1].[ItemId] AS [K2], 
         COUNT(1) AS [A1], 
         COUNT(1) AS [A2]
       FROM [dbo].[TestTable] AS [Extent1]
       WHERE 64025 = [Extent1].[GroupId]
       GROUP BY [Extent1].[GroupId], [Extent1].[ItemId]
     )  AS [GroupBy1]
ORDER BY [GroupBy1].[K1] ASC, [GroupBy1].[A1] DESC
这同样有效,但比我创建的SQL慢了一倍

我已经摆弄linq代码有一段时间了,但我还没有创建类似于我的查询的东西

执行计划(仅最后两项,前两项相同):


实体框架生成的查询和您手工编制的查询在语义上是相同的,并且将给出相同的计划

在查询优化期间,派生表定义是内联的,因此唯一的区别可能是在解析和编译期间产生一些非常小的额外开销

您发布的
SHOWPLAN\u TEXT
片段与计划相同。唯一的区别是别名。看起来您的表定义类似于

CREATE TABLE [dbo].[TestTable] 
(
[GroupId] INT,
[ItemId] INT
)

CREATE NONCLUSTERED INDEX IX_Group ON  [dbo].[TestTable] ([GroupId], [ItemId]) 
你有这样的计划吗


无论出于何种目的,这些计划都是相同的。您的性能测试方法可能有缺陷。例如,您的第一个查询可能将页面带到缓存中,然后使第二个查询受益。

Entity Framework生成的查询和您手工创建的查询在语义上是相同的,并且将给出相同的计划

在查询优化期间,派生表定义是内联的,因此唯一的区别可能是在解析和编译期间产生一些非常小的额外开销

您发布的
SHOWPLAN\u TEXT
片段与计划相同。唯一的区别是别名。看起来您的表定义类似于

CREATE TABLE [dbo].[TestTable] 
(
[GroupId] INT,
[ItemId] INT
)

CREATE NONCLUSTERED INDEX IX_Group ON  [dbo].[TestTable] ([GroupId], [ItemId]) 
你有这样的计划吗


无论出于何种目的,这些计划都是相同的。您的性能测试方法可能有缺陷。例如,您的第一个查询可能将页面带入缓存,然后第二个查询从中受益。

为什么不使用LINQ中的顶级功能?至少在Lambdas中存在(top、skip函数)。你的速度差可能会拉动所有元素,而不是前1000名。EF版本?他们致力于创建更好的SQL。@TomTom,我知道它存在,我需要所有数据,但TOP查询只是我自己的一个快速测试。我把它从问题中删除了,所以请忽略:)嗯,闻起来像坏的SQL——EF就是这样出名的。不确定能做多少。您使用哪个EF版本?使用5 adand mabe 6会更好,否则您可以在codeplex的EF端询问,开发人员可能会加入。执行计划是什么?错误的统计数据可能会导致等价查询的不同计划。执行计划是相同的。只有名称不同。为什么不使用LINQ中的顶级功能?至少在Lambdas中存在(top、skip函数)。你的速度差可能会拉动所有元素,而不是前1000名。EF版本?他们致力于创建更好的SQL。@TomTom,我知道它存在,我需要所有数据,但TOP查询只是我自己的一个快速测试。我把它从问题中删除了,所以请忽略:)嗯,闻起来像坏的SQL——EF就是这样出名的。不确定能做多少。您使用哪个EF版本?使用5 adand mabe 6会更好,否则您可以在codeplex的EF端询问,开发人员可能会加入。执行计划是什么?错误的统计数据可能会导致等价查询的不同计划。执行计划是相同的。只是名字不同。谢谢,很有趣。我用10000次迭代多次测试了这两个变体,我自己的sql代码总是快了近2倍。TestTable只包含另一列(仅包含名为SetId的整数),我不怀疑这会导致差异?PK设置在所有三个列(SetId、GroupId、ItemId)上,非聚集索引设置在GroupId、SetId上。您发布的执行计划图形看起来确实与我在这里看到的类似。因为你的帖子,我再次测试了这个,现在我确实看到了类似的结果。也许这毕竟只是某个地方的温度差异。@Areius-您是在测试实际的原始查询还是EF相对于从
C
发送的原始查询的性能?EF有编译查询的开销,除非您使用编译后的查询。这两个都来自EF,我自己使用EF的“SqlQuery”方法。谢谢,非常有趣。我用10000次迭代多次测试了这两个变体,我自己的sql代码总是快了近2倍。TestTable只包含另一列(仅包含名为SetId的整数),我不怀疑这会导致差异?PK设置在所有三个列(SetId、GroupId、ItemId)上,非聚集索引设置在GroupId、SetId上。您发布的执行计划图形看起来确实与我在这里看到的类似。因为你的帖子,我再次测试了这个,现在我确实看到了类似的结果。也许这毕竟只是某个地方的温度差异。@Areius-您是在测试实际的原始查询还是EF相对于从
C
发送的原始查询的性能?EF有编译查询的开销,除非您使用编译后的查询。这两个都来自EF,我自己使用EF的“SqlQuery”方法。