寻找LINQ的界限

时间:2013-06-06 02:20:00

标签: 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

2 个答案:

答案 0 :(得分: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();

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();

答案 1 :(得分: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();