1

这段代码工作正常,但我想知道是否没有某种方法可以在一个 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
4

2 回答 2

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();
于 2013-06-06T02:32:10.057 回答
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();
于 2013-06-06T02:37:07.187 回答