我想知道为什么下面的两个EF Core查询返回相同的东西,实际上是在不同的SQL语句中翻译。我怎么能把第一个写成lambda表达式?它似乎更有效率。
查询1
var query = from d in _context.Devices
from e in _context.Events.Where(e => e.DeviceId == d.DeviceId).Take(1)
select new
{
deviceId = d.DeviceId,
lat = d.Lat,
lon = d.Lon,
events = e
};
这个翻译在下面的SQL中(简化):
SELECT *
FROM [Devices] AS [d]
CROSS APPLY (
SELECT TOP(1) *
FROM [Events] AS [e]
WHERE [e].[DeviceId] = [d].[DeviceId]
) AS [t]
查询2
var query = _context.Devices.Select(d => new
{
deviceId = d.DeviceId,
lat = d.Lat,
lon = d.Lon,
events = d.Events.Take(1)
});
这个而不是使用APPLY,它首先选择Devices,然后为每个SELECT选择TOP 1事件:
/* run first */
SELECT *
FROM [Devices] AS [d]
/* run for each device */
SELECT TOP(1) *
FROM [Events] AS [e]
WHERE @_outer_DeviceId = [e].[DeviceId]
答案 0 :(得分:1)
感谢@IvanStoev,我注意到这两个查询基本不同:
第一个返回平面结果集基本上(设备,事件) 对,而第二个返回(设备,事件列表)对
通过使用TOP(2)
更改事件数量可以看出这一点:
查询1:
[
{
"deviceId": 1,
"lat": 51.44467,
"lon": -0.21289,
"events": {
"min": 1.27,
"max": 11.1,
"eventId": 24873
}
},
{
"deviceId": 1,
"lat": 51.44467,
"lon": -0.21289,
"events": {
"min": 1.27,
"max": 11.1,
"eventId": 24852
}
},
{
"deviceId": 2,
"lat": 51.48085,
"lon": -0.16862,
"events": {
"min": 32.61,
"max": 37.24,
"eventId": 224693
}
},
{
"deviceId": 2,
"lat": 51.48085,
"lon": -0.16862,
...
查询2:
[
{
"deviceId": 1,
"lat": 51.44467,
"lon": -0.21289,
"events": [
{
"min": 1.27,
"max": 11.1,
"eventId": 24873
},
{
"min": 1.27,
"max": 11.1,
"eventId": 24852
}
]
},
{
"deviceId": 2,
"lat": 51.48085,
"lon": -0.16862,
"events": [
{
"min": 32.61,
"max": 37.24,
"eventId": 224693
},
{
"min": 32.61,
"max": 37.24,
"eventId": 224689
}
]
},
{
"deviceId": 3,
"lat": 51.4488,
"lon": -0.1493,
"events": [
{
...