在1到n个关系实体中按组查询列表的最佳方法

时间:2017-12-05 03:54:15

标签: c# entity-framework linq group-by entity-framework-core

我希望查询只显示列表中所有工作人员的最后位置。 我知道我必须在这种情况下使用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);
    }
}

1 个答案:

答案 0 :(得分:1)

让我们忘记实体框架和async并使用数据模型。

PositionsICollection,表示没有特定的顺序。所以要获得出租车的最后位置

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。您现在已获得所有出租车的最后位置。