我希望查询只显示列表中所有工作人员的最后位置。 我知道我必须在这种情况下使用group by,但我不知道最好的方法是什么。我用了很多方法来做到这一点,但我觉得有些问题加上我在使用group by的ToListAsync()时遇到了问题,我更喜欢使用queryable进行查询而不是枚举以获得最佳性能。我在两三天前搜索过,我发现group by不适用于包含和其他一些问题。 这是我的代码:
public class WorkerTaxi : Worker
{
#region MainProperties
........
#endregion
#region EFRelations
......
[InverseProperty(property: "WorkerTaxi")]
public virtual ICollection<Car> Cars { get; set; }
[InverseProperty(property: "WorkerTaxi")]
public virtual ICollection<Position> Positions { get; set; }
#endregion
}
public class Position
{
[Required]
public Guid PositionId { get; set; }
[Required]
public double GeoLocationLat { get; set; }
[Required]
public double GeoLocationLong { get; set; }
[Required]
public DateTime Date { get; set; }
[ForeignKey("PersonId")]
[InverseProperty(property: "Positions")]
public virtual WorkerTaxi WorkerTaxi{get; set; }
[Required]
public Guid PersonId { get; set; }
}
public async Task<ReadOnlyCollection<PositionViewModel>>
GetAllWorkerTaxiLastPositionByCityAsync(string cityName)
{
var hashing = new Hashing(text: cityName);
var hash = hashing.GetHash();
var workerList = await (from x in _workerTaxi.Include(x=>x.Positions)
where hashing.GetHashFromEncryption(x.City.CityName) == hash && x.IsReadyForWork
select x)
.ToListAsync();
var workerWithLastPositions = workerList.GroupBy(
p => p.PersonId,
p => p.Positions.OrderByDescending(x=>x.Date).FirstOrDefault(),
(key, g) => new Position{ PersonId = key,GeoLocationLat= g.FirstOrDefault().GeoLocationLat,GeoLocationLong = g.FirstOrDefault().GeoLocationLong }).ToList();
return _mapper.Map<ReadOnlyCollection<PositionViewModel>>(workerWithLastPositions);
}
}
答案 0 :(得分:1)
让我们忘记实体框架和async
并使用数据模型。
Positions
是ICollection
,表示没有特定的顺序。所以要获得出租车的最后位置
Positions
.Where(p => p.WorkerTax == ...)
.OrderByDescending(p => p.Date)
.First()
如你所说,我们可以按出租车对这些职位进行分组,然后采取最后的立场。
Positions
.OrderByDescending(p => p.Date)
.GroupBy(p => p.taxi)
.Select(g => g.First())
一个位置包含taxi
,所以你需要的只是dow
。您现在已获得所有出租车的最后位置。