2016-08-23 1 views
3

모든 차량이 등록 된 테이블과 각 등록 된 차량에 대해 수백만 개의 핑이있는 테이블이 있습니다.LINQ 목록을 사용하여 DB에서 마지막 고유 레코드 선택

LINQ QUERY를 사용하여 지난 30 분 동안 ping을 보낸 각 차량에서 마지막 ping을 선택하려고합니다. "for each"아이디어를 통해 아래 코드를 작성했지만 최선의 방법인지는 확실하지 않습니다.

단일 라인을 사용하여 이것을 선택하는 더 좋은 방법이 있는지 알고 싶습니다. 내가 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(); 

테이블 모두에 가입하고 GroupBy 사용하여 데이터베이스에서 수행해야,

답변

2

네, 감사합니다 대신

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.ToArray 또는 ToList 사용할 수 있습니다, 네가 뭘하고 싶은지 모르겠다.

+0

안녕하세요 @Tim Schmelter. 도움 주셔서 감사합니다. 이미지가 표시되면 https://postimg.org/image/pc3agbm75/, LINQ는 전체 데이터베이스를 선택한 다음 필터를 적용합니다. 현재 약 63884 개의 행이 있기 때문에 약 7 초가 걸립니다. 를 위해 각각을 사용하면 전체 데이터를 선택하는 데 1 초가 걸립니다. 어쨌든 각각에 대해 마지막 ping 만 선택 하시겠습니까? – Canela

2

당신이 .maxby() 메소드를 찾을 수 nuget에서 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' 열은 Vehicle 테이블 안에 마지막 ping 정보를 가지고 있습니다. 왜냐하면'Tracks' 테이블을 선택하지 않고 다른 검사를하는 데 도움이되기 때문입니다. 그러나 모든 ping 정보는 Track 테이블 안에 있습니다. 차량 1, 2 및 3이 차량 테이블 안에 있다고 가정 해 봅니다. 'Track' 테이블은 모든 차량에 대해 1 백만개 이상의 핑을 가질 수 있습니다. 내가하려는 것은 트랙 테이블이 커질 것이므로 모든 것을 선택하지 않고 마지막 차량의 핑을 선택하는 것입니다. – Canela

관련 문제