我有一个ASP.NET Core应用程序,可通过EF Core在SQL Server 2012上运行。我要实现的是计算像这样的不同群体的人数
from b in this._context.Benchmark
group b by b.Device into g
select new {
Device = g.Key,
Count = g.Count()
}
问题是整个过程非常缓慢,其原因似乎是SQL语句未映射到GROUP BY
和COUNT(*)
,但根据调试器,应用程序请求所有内容并在CPU上执行计数。我从调试器的事件窗口中获得的查询如下:
SELECT [b0].[ID], [b0].[CreateDate], [b0].[Creator], [b0].[Device], [b0].[Environment], [b0].[Machine], [b0].[Name], [b0].[Plugin], [b0].[RunDate]
FROM [Benchmark] AS [b0]
ORDER BY [b0].[Device]
我还可以看到,对于简单的COUNT()
来说,用于调试的IIS Express的内存消耗是疯狂的,因此我倾向于认为这是实际的查询。
问题是:如何重新定义查询,使其实际上映射到COUNT()
?
编辑:我已经在“真实” EF和ctx.Database.Log = Console.Write
上尝试了相同的查询,这产生了预期的COUNT()
查询,这使我相信这是一个EF Core。
答案 0 :(得分:0)
请将EF Core升级到2.1.2版。
答案 1 :(得分:0)
LINQ表达式'GroupBy([x.Device],[x])'无法翻译 并将在本地进行评估。
LINQ表达式'Count()'无法翻译,将被翻译为 本地评估。
上面的日志来自我后来的测试结果,表明尚不支持render
和<QueryRenderer
environment={environment}
query={graphql`
query MyQuery($exampleUserId: String!) {
user(userId: $exampleUserId) {
favoriteIceCream
}
}
`}
render={({ error, props, retry }) => {
// Here, you could call `retry()` to refetch data
// or pass it as a prop to a child component.
return (
<IceCreamSelectionView refetchData={retry} user={props.user} />
)
}} />
来将完整的LINQ转换为SQL,然后直接在数据库中执行完整的SQL, EF Core必须首先获取所有数据,然后在本地获取GroupBy
结果。因此,如果您的数据量很大,那么性能将非常糟糕。
您必须对简单的SQL进行硬编码才能直接在数据库中进行工作,然后性能才能恢复正常。
我升级到EF Core 2.1.2,在Count()
和GroupBy
中都尝试了以下代码:
MySQL
结果选择器位于MS SQL
内部,这将确保是否可以将其转换为正确的SQL,不幸的是,不是。
这是另一个难题,请避免使用var query = _context.Benchmark.GroupBy(x => x.Device,
(key, group) => new //Result selector
{
Device = key,
Count = group.Count()
});
await query.ToListAsync();
:
GroupBy
C#代码通过retry
function生成以下日志:
Count
这是核心LOGS,它显示尚不支持var query = _context.Benchmark.GroupBy(x => x.Device,
(key, group) => new //Result selector
{
Device = key,
Count = group.Select(g => g.Id)//Avoid to use Count
});
await query.ToListAsync();
:
2018-08-24T14:27:26.6737424-04:00 Information 10403 Microsoft.EntityFrameworkCore.Infrastructure Entity Framework Core 2.1.2-rtm-30932 initialized 'ApplicationDbContext' using provider 'Pomelo.EntityFrameworkCore.MySql' with options: None 2018-08-24T14:27:31.4270317-04:00 Debug 10101 Microsoft.EntityFrameworkCore.Query Compiling query model: 'from IGrouping<Device, Benchmark> <generated>_0 in (from Benchmark x in DbSet<Benchmark> select [x]).GroupBy([x].Device, [x]) select new <>f__AnonymousType3<Device, int>( [<generated>_0].Key, (from Benchmark <generated>_1 in [<generated>_0] select [<generated>_1]).Count() )' 2018-08-24T14:27:31.4319437-04:00 Debug 10104 Microsoft.EntityFrameworkCore.Query Optimized query model: 'from IGrouping<Device, Benchmark> <generated>_0 in (from Benchmark x in DbSet<Benchmark> join Device x.Device in DbSet<Device> on Property([x], "DeviceId") equals Property([x.Device], "Id") select [x]).GroupBy([x.Device], [x]) select new <>f__AnonymousType3<Device, int>( [<generated>_0].Key, (from Benchmark <generated>_1 in [<generated>_0] select [<generated>_1]).Count() )'
以下是休息日志:
GROUPBY
这是我的环境:
2018-08-24T14:27:31.4431635-04:00 Warning 20500 Microsoft.EntityFrameworkCore.Query
The LINQ expression 'GroupBy([x.Device], [x])' could not be translated and will be evaluated locally.
2018-08-24T14:27:31.4476637-04:00 Warning 20500 Microsoft.EntityFrameworkCore.Query
The LINQ expression 'Count()' could not be translated and will be evaluated locally.
2018-08-24T14:27:31.4511652-04:00 Warning 20500 Microsoft.EntityFrameworkCore.Query
The LINQ expression 'Count()' could not be translated and will be evaluated locally.