2013-06-06 4 views
1

Этот код работает нормально, но мне было интересно, нет ли способа записать его в одном выражении LINQ, так что один проход может быть выполнен сервером базы данных вместо того, чтобы реализовать набор результатов, а затем цикл через него, что и будет делать мой код.Поиск границ с помощью LINQ

var logs = from AssetLog log in dc.AssetLogs 
      where log.AssetId == assetId && log.Recorded >= start && log.Recorded <= finish 
      select log; 
    return new GetInteractionBoundsResult() 
    { 
    N = logs.Max(log => log.Latitude), 
    S = logs.Min(log => log.Latitude), 
    W = logs.Min(log => log.Longitude), 
    E = logs.Max(log => log.Longitude) 
    }; 

Так, LINQ гуру, как бы вы написали выше, так что она производит более или менее это в базе данных:

SELECT MIN(Latitude) S, MAX(Latitude) N, MIN(Longitude) W, MAX(Longitude) E 
FROM ASSETLOG WHERE etc etc 

ответ

1

Конечно, просто обмануть ваш провайдер LINQ в думая, что это по-прежнему работает с запрос до самого конца:

var logs = from asset in dc.Assets 
      where asset.AssetId == assetId 
      let g = asset.AssetLogs 
       .Where(log => log.Recorded >= start && log.Recorded <= finish) 
      select new GetInteractionBoundsResult 
       { 
        N = g.Max(log => log.Latitude), 
        S = g.Min(log => log.Latitude), 
        W = g.Min(log => log.Longitude), 
        E = g.Max(log => log.Longitude) 
       }; 
    return logs.Single(); 

A Group By может работать лучше, чем присоединиться, что выше запрос будет производить:

var logs = from log in dc.AssetLogs 
      where log.AssetId == assetId && 
       log.Recorded >= start && log.Recorded <= finish 
      group log by log.AssetId into g 
      select new GetInteractionBoundsResult 
       { 
        N = g.Max(log => log.Latitude), 
        S = g.Min(log => log.Latitude), 
        W = g.Min(log => log.Longitude), 
        E = g.Max(log => log.Longitude) 
       }; 
    return logs.Single(); 
+0

Я уверен, что 'logs' не сможет ссылаться на себя. – dahlbyk

+0

@ dahlbyk: Было несколько опечаток, извините. – StriplingWarrior

+0

groupby to, должен был подумать об этом, спасибо –

0

Это займет довольно сложный поставщик LINQ, но подзапрос может работать:

var res = from asset in dc.Assets 
      where log.AssetId == assetId 
      let logs = (from AssetLog log in asset.AssetLogs 
         where log.Recorded >= start && log.Recorded <= finish 
         select log) 
      select new GetInteractionBoundsResult() 
      { 
       N = logs.Max(log => log.Latitude), 
       S = logs.Min(log => log.Latitude), 
       W = logs.Min(log => log.Longitude), 
       E = logs.Max(log => log.Longitude) 
      }; 
    return res.Single(); 
+0

Это * есть довольно сложный провайдер: Linq2Sql. И тебе спасибо. groupby был тем, о чем я пытался думать. –

Смежные вопросы