Выберите TOP 1 для каждого FK в списке, используя Entity Framework - PullRequest
1 голос
/ 19 сентября 2019

У меня есть большая таблица, где я пытаюсь выбрать строку top 1 для каждого FK в списке.

Моя таблица имеет вид:

ChangeId | AssetId | Timestamp
1          1         123
2          2         999
3          1         3478
4          3         344
5          2         1092

ГдеChangeId - это мое PK, AssetId - это мое FK, а Timestamp - это значение, которое я пытаюсь выбрать.

Если я попытаюсь сделать следующее:

var results =

from Asset in _context.Asset
join change in _context.Change on Asset.AssetId equals change.AssetId into potentialChange
from actualChange in potentialChange.OrderByDescending(y => y.ChangeId).Take(1)
select 
{
   AssetId,
   Timestamp
}

Где мой ожидаемый результат будет:

[
  {
    AssetId: 1,
    Timestamp: 3478
  },
  {
    AssetId: 2,
    Timestamp: 1092
  },
  {
    AssetId: 3,
    Timestamp: 344
  }
]

Этот запрос отображает The LINQ expression could not be translated and will be evaluated locally., который не подходит для развертывания производства.

Запуск цикла foreach и выбор каждого1 из 1 работает, а не является эффективным решением.

Есть ли подходящий способ для достижения вышеизложенного?

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Попробуйте сгруппировать его по AssetId и взять максимум из каждой группы

var results =

from Asset in _context.Asset
join change in _context.Change on Asset.AssetId equals change.AssetId into potentialChange
group potentialChange by potentialCharge.AssetId into g
select 
{
    g.Key,
    g.Max().Timestamp
}
0 голосов
/ 19 сентября 2019

Используйте Group By следующим образом:

List<MyTable> data = new List<MyTable>()
{
     new MyTable(){ChangeId = 1, AssetId = 1, Timestamp = 123},
     new MyTable(){ChangeId = 2, AssetId = 2, Timestamp = 999},
     new MyTable(){ChangeId = 3, AssetId = 1, Timestamp = 123},
     new MyTable(){ChangeId = 5, AssetId = 3, Timestamp = 123},
     new MyTable(){ChangeId = 5, AssetId = 2, Timestamp = 123},
};

var expectedData = data.OrderByDescending(d => d.Timestamp).GroupBy(d => d.AssetId).Select(g => new
{
     AssetId = g.Key,
     TimeStamp = g.First().Timestamp

}).ToList();

Это даст ожидаемый результат.

0 голосов
/ 19 сентября 2019

Попробуйте использовать .First() вместо .Take(1)

LINQ Как взять одну запись и пропустить остаток c #

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...