EF Lambda查询-计算每个项目?

时间:2019-01-21 00:49:29

标签: c# entity-framework linq lambda

我正在使用一项服务来收集物品。我想计算结果中每个项目与地理坐标的距离,但是我不知道如何使用lambda将其添加到现有服务查询中。

这是我获取数据的方式:

IEnumerable<Listing> items = await _listingService.Query(x => x.CategoryID 
        == model.CategoryID || keys.Any(c => c == x.CategoryID))
                    .Include(x => x.ListingPictures)
                    .Include(x => x.Category)
                    .SelectAsync();

这是我使用LINQ来获取距离的方式,但是在运行以上语句之后,这是使用items集合:

double lat = 41.2;
double lon = -71.01;
DbGeography point = DbGeography.FromText(String.Format(CultureInfo.InvariantCulture, "POINT({0} {1})", lon, lat));

List<Listing> items1 = new List<Listing>(from g in items
                          let distance = g.Geolocation.Distance(point)
                          orderby distance
                          select new Listing()
                             {
                                 ID = g.ID,                               
                                 CategoryID = g.CategoryID,
                                 Title = g.Title,
                                 Description = g.Description,
                                 Price = g.Price,
                                 Location = g.Location,
                                 Created = g.Created,
                                 DistanceInMiles = (distance / 1609.344),
                             });
    items = items1;

这不起作用,因为它丢失了第一个查询中Include()语句中的所有关系。我不知道如何在第一个服务Lambda查询中使用类似let的关键字来执行相同的操作。我正在尝试不查询两次。有没有一种方法可以在第一个服务查询lambda中计算一个字段,以便我可以将距离添加到每个项目中?

我认为使用projections可能有用,但我无法使用它。

2 个答案:

答案 0 :(得分:2)

items1是一组全新的Listing对象,您不是在“更新”现有对象的值。因此,因为您没有复制ListingPicturesCategory属性,所以它们将为null。您需要在投影中执行以下操作:

select new Listing()
{
    ID = g.ID,                               
    CategoryID = g.CategoryID,
    Title = g.Title,
    Description = g.Description,
    Price = g.Price,
    Location = g.Location,
    Created = g.Created,
    DistanceInMiles = (distance / 1609.344),
    ListingPictures = g.ListingPictures, //Add this line
    Category = g.Category //and this line
});

或者,您似乎只是在尝试更新DistanceInMiles属性,而通过简单的foreach循环可能会更好。

答案 1 :(得分:0)

我认为在这种情况下使用linq会使语句的可读性降低,但是下面是处理方法:

List<Listing> items1 = items.Select(g => select new Listing()
                             {
                                 ID = g.ID,                               
                                 CategoryID = g.CategoryID,
                                 Title = g.Title,
                                 Description = g.Description,
                                 Price = g.Price,
                                 Location = g.Location,
                                 Created = g.Created,
                                 DistanceInMiles = (g.Geolocation.Distance(point) / 1609.344),
                             });
相关问题