Не удалось перевести выражение LINQ «GroupBy ([x.Device], [x])», и оно будет оцениваться локально.
Невозможно выполнить выражение LINQ «Count ()»переведен и будет оцениваться локально.
Приведенные выше журналы взяты из моих более поздних результатов испытаний, которые показывают, что GroupBy
& Count()
пока не поддерживаются для перевода полного LINQ в SQL, а затем непосредственно выполняютсяполный SQL в базе данных, теперь EF Core должен сначала получить все данные, а затем GroupBy
результаты локально.Итак, если ваши данные огромны, то производительность будет очень плохой.
Вам придется жестко программировать простой SQL, чтобы напрямую работать с базой данных, тогда производительность вернется к норме.
Я обновился до EF Core 2.1.2, попробовал следующий код в MySQL
и MS SQL
:
var query = _context.Benchmark.GroupBy(x => x.Device,
(key, group) => new //Result selector
{
Device = key,
Count = group.Count()
});
await query.ToListAsync();
Селектор результатов находится прямо внутри GroupBy
, что приведет куверен, может ли он быть переведен на правильный SQL, но, к сожалению, это НЕ.
Вот еще один хитрый способ, избегайте использования Count
:
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();
Код C # создает следующие журналы этот инструмент :
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.
Вот журналы отдыха после:
2018-08-24T14:27:31.4608060-04:00 Debug 10107 Microsoft.EntityFrameworkCore.Query
(QueryContext queryContext) => IAsyncEnumerable<<>f__AnonymousType3<Device, int>> _InterceptExceptions(
source: IAsyncEnumerable<<>f__AnonymousType3<Device, int>> _SelectAsync(
source: IAsyncEnumerable<IGrouping<Device, ValueBuffer>> _GroupBy(
source: IAsyncEnumerable<TransparentIdentifier<ValueBuffer, Device>> _ShapedQuery(
queryContext: queryContext,
shaperCommandContext: SelectExpression:
SELECT `x.Device`.`Id`, `x.Device`.`Description`, `x.Device`.`IP`, `x.Device`.`Name`, `x.Device`.`Port`
FROM `Benchmark` AS `x`
INNER JOIN `Device` AS `x.Device` ON `x`.`DeviceId` = `x.Device`.`Id`
ORDER BY `x.Device`.`Id`,
shaper: TypedCompositeShaper<ValueBufferShaper, ValueBuffer, BufferedOffsetEntityShaper<Device>, Device, TransparentIdentifier<ValueBuffer, Device>>),
keySelector: (TransparentIdentifier<ValueBuffer, Device> t0) => t0.Inner,
elementSelector: (TransparentIdentifier<ValueBuffer, Device> t0) => t0.Outer),
selector: (IGrouping<Device, ValueBuffer> <generated>_0 | CancellationToken ct) => Task<<>f__AnonymousType3<Device, int>> _ExecuteAsync(
taskFactories: new Func<Task<object>>[]{ () => Task<object> _ToObjectTask(Task<int> Count(
source: IAsyncEnumerable<ValueBuffer> _ToAsyncEnumerable(<generated>_0),
cancellationToken: queryContext.CancellationToken)) },
selector: (object[] results) => new <>f__AnonymousType3<Device, int>(
<generated>_0.Key,
(int)results[0]
))),
contextType: Sequencer.Updater.Data.ApplicationDbContext,
logger: DiagnosticsLogger<Query>,
queryContext: queryContext)
2018-08-24T14:27:31.4825759-04:00 Debug 20000 Microsoft.EntityFrameworkCore.Database.Connection
Opening connection to database 'TestDB' on server 'localhost,3306'.
2018-08-24T14:27:31.4877302-04:00 Debug 20001 Microsoft.EntityFrameworkCore.Database.Connection
Opened connection to database 'TestDB' on server 'localhost,3306'.
2018-08-24T14:27:31.4901269-04:00 Debug 20100 Microsoft.EntityFrameworkCore.Database.Command
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT `x.Device`.`Id`, `x.Device`.`Description`, `x.Device`.`IP`, `x.Device`.`Name`, `x.Device`.`Port`
FROM `Benchmark` AS `x`
INNER JOIN `Device` AS `x.Device` ON `x`.`DeviceId` = `x.Device`.`Id`
ORDER BY `x.Device`.`Id`
2018-08-24T14:27:31.4929857-04:00 Information 20101 Microsoft.EntityFrameworkCore.Database.Command
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT `x.Device`.`Id`, `x.Device`.`Description`, `x.Device`.`IP`, `x.Device`.`Name`, `x.Device`.`Port`
FROM `Benchmark` AS `x`
INNER JOIN `Device` AS `x.Device` ON `x`.`DeviceId` = `x.Device`.`Id`
ORDER BY `x.Device`.`Id`
2018-08-24T14:27:31.5231128-04:00 Debug 20300 Microsoft.EntityFrameworkCore.Database.Command
A data reader was disposed.
2018-08-24T14:27:31.5270399-04:00 Debug 20002 Microsoft.EntityFrameworkCore.Database.Connection
Closing connection to database 'TestDB' on server 'localhost,3306'.
2018-08-24T14:27:31.5303748-04:00 Debug 20003 Microsoft.EntityFrameworkCore.Database.Connection
Closed connection to database 'TestDB' on server 'localhost,3306'.
Вот мое окружение:
PM> dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 2.1.401
Commit: 91b1c13032
Runtime Environment:
OS Name: Windows
OS Version: 10.0.16299
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\2.1.401\
Host (useful for support):
Version: 2.1.3
Commit: 124038c13e
.NET Core SDKs installed:
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.302 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]