2016-08-23 95 views
3

我有一张表,其中所有车辆都已注册,另一张表中我为每辆注册车辆配备了数百万个ping。LINQ从数据库中选择最后和唯一记录使用列表

我想从使用LINQ QUERY的最近30分钟内发送ping的每辆车选择最后一次ping。我已经通过“为每个”理念完成了下面的代码,但我不确定这是否是最好的方法。

我想知道是否有更好的方法来选择使用一条线?我知道我可以通过vehicle_fleetNumber“对它们进行分组”,但由于TAKE()限制了最终结果,所以我无法达到正确的结果。

var timeRestriction = DateTime.UtcNow.AddMinutes(-30); 
var x = _db.Vehicles.Where(r=> r.isActive.Equals(true) && r.helperLastPing > timeRestriction); 

foreach (var vehicle in x) 
{ 
    var firstOrDefault = _db.Tracks.OrderByDescending(r => r.collectedOn) 
     .FirstOrDefault(r => r.vehicle_fleetNumber.Equals(vehicle.fleetNumber)); 
} 

return View(); 

谢谢

回答

2

是的,你应该做它在数据库中通过连接两个表,并使用GroupBy

var query = from v in _db.Vehicles 
      join t in _db.Tracks 
      on v.fleetNumber equals t.vehicle_fleetNumber 
      where v.isActive && v.helperLastPing > timeRestriction 
      group t by t.vehicle_fleetNumber into vehicleGroup 
      select vehicleGroup.OrderByDescending(x => x.collectedOn).First(); 

foreach(var track in query) 
{ 
    // ... 
} 

取而代之的foreach你也可以使用query.ToArrayToList,我不知道你想用它做什么。

+0

Hi @Tim Schmelter。 谢谢你的帮助。 如果您看到图像https://postimg.org/image/pc3agbm75/,则LINQ选择整个数据库,然后应用过滤器。这需要大约7秒钟,这是因为我目前只有63884行。使用它为每个需要1秒选择整个数据。 反正有没有为每个选择最后的ping? – Canela

2

如果您的NuGet你会发现.maxby()方法得到moreLinq:在不同的上下文 例如:

//get the correct exchange rate 
var rateList = _db.lists_ExchangeRates.Where(
      rates => rates.Currency == currencyCode); 
      Decimal? exRate = rateList.MaxBy(rates => rates.LastUpdated).ExchangeRate; 

参看下面这提供了额外的信息。

MoreLinq maxBy vs LINQ max + where

+0

我试过了,但是我得到了异常System.OutOfMemoryException,因为它可能读取了超过65k行的整个表。请参阅下面的代码 'var query = _db.Tracks.Where(r => r.Vehicle.isActive && r.Vehicle.helperLastPing> timeRestriction); var maxBy = query.MaxBy(track => track.vehicle_fleetNumber);' 感谢您的帮助 – Canela

+0

您可以通过在SQL服务器端引入视图并查询该视图来限制结果。它应该使数据更快更容易地工作。 –

0

在我而言,如果我想这已经节省我用这个方法

var id = db.DPSlips.Max(item => item.Id);

所以我想这可能会奏效,这将只是尝试

var timeRestriction = DateTime.UtcNow.AddMinutes(-30); var x = _db.Vehicles.Max(a => a.isActive == true && a.helperLastPing > timeRestriction);最后数据

+0

感谢队友 它只会选择车辆信息和车辆,并平有不同的表。 的'helperLastPing'列有车辆表内的最后一个平信息,因为它可以帮助我做其他的检查,而不选择'Tracks'表,但所有的ping请求的信息是跟踪表内。 假设我在车辆表中有车辆1,2和3。每个车辆的“轨道”表可能有100万坪或更多。 我想要做的是选择每个最后的车辆的平,而没有选择所有的轨道表将是巨大的。 – Canela