EF Core: как выбрать последние элементы с сохранением результата IQueryable? - PullRequest
0 голосов
/ 05 мая 2020

Допустим, у меня есть такая модель:

class Price {
    [Key]
    string ItemId { get; set; }
    string TypeId { get;set;
    [Key]
    string ValidFrom { get;set; }
    decimal Value { get;set; }
}

Мне нужно объединить продукты с ценами, действующими на определенную дату. Модель товара не важна. Его можно найти по ItemId.

Я попытался узнать, скажем так, последние цены:

    var latestPrices =
        Data.Prices
            .GroupBy(e => e.ItemId)
            .Select(i => i.First(j => j.ValidFrom == i.Max(k => k.ValidFrom)))

Просто и очевидно, не так ли? Не для EF. Это дает InvalidOperationException, потому что EF не знает, как построить из этого запрос SQL. Я могу использовать ToList между ними, но я бы предпочел более элегантное решение. Что-то, что все еще может быть IQueryable<T>. Возможно ли это?

Сейчас я подумываю о преобразовании результата в список, поскольку считается, что количество данных не является излишним для производительности.

Тогда я рассматриваю возможность введения дополнительных уникальных id для модели Price и добавляйте ее к каждой покупке. Это было бы очень легко сделать для новых покупок, но хлопотно для уже имеющихся. Мне нужно создать большой и медленный запрос, чтобы найти подходящие идентификаторы и заполнить пробелы.

Когда я впервые представил свойство ValidFrom, чтобы иметь своего рода историю цен, это казалось таким простым. У нас есть все данные для определения цены в любой день, но теперь я не знаю, как объяснить эту идею Entity Framework;)

РЕДАКТИРОВАТЬ: Погодите !!! Кажется, работает:

var q1 = Data.Prices.Where(/* yada yada yada */);
var q2 = q1.Where(i =>
    i.ValidFrom == q1.Where(j => j.TypeId == i.TypeId).Max(k => k.ValidFrom));

То есть я поставил var result = q2.toArray() и не бросает! На самом деле это дает разумные результаты примерно за 20 мс, что является разумным временем для моей настройки - так что ... Это все? EF не может использовать GroupBy, но с подзапросами это нормально?

Очень важно, чтобы я получил последнее значение для каждого TypeId, мой последний запрос в порядке?

...