Допустим, у меня есть такая модель:
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
, мой последний запрос в порядке?