我正在使用一项服务来收集物品。我想计算结果中每个项目与地理坐标的距离,但是我不知道如何使用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可能有用,但我无法使用它。
答案 0 :(得分:2)
items1
是一组全新的Listing
对象,您不是在“更新”现有对象的值。因此,因为您没有复制ListingPictures
和Category
属性,所以它们将为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),
});