实体框架核心以不同方式查询相关条目

时间:2017-04-26 17:22:33

标签: sql entity-framework

我想知道为什么下面的两个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]

1 个答案:

答案 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": [
    {
 ...