EF Lambda Query - расчет для каждого предмета? - PullRequest
0 голосов
/ 21 января 2019

Я получаю коллекцию предметов, используя сервис. Я хочу вычислить расстояние от географической координаты для каждого элемента в результатах, но я не знаю, как добавить это к существующему запросу службы с помощью лямбды.

Вот как я получаю данные:

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() в первом запросе. Я не могу понять, как сделать то же самое, используя ключевое слово let в первом лямбда-запросе службы. Я пытаюсь не запрашивать дважды. Есть ли способ вычислить поле в первом лямбда-запросе службы, чтобы я мог добавить расстояние к каждому элементу?

Я думал, что использование проекций может сработать, но я не смог этого сделать.

Ответы [ 2 ]

0 голосов
/ 21 января 2019

items1 - это совершенно новый набор объектов Listing, вы не «обновляете» значения существующего. Поэтому, поскольку вы не копируете свойства ListingPictures и Category, они будут нулевыми. Вы должны сделать что-то подобное в своей проекции:

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.

0 голосов
/ 21 января 2019

Я думаю, что использование 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),
                             });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...