Если вы хотите, чтобы последняя запись узла имела статус «Ожидание», и при условии, что у вас может быть узел, который переключился на «Ожидание» более одного раза: то есть
node ID Status Time
1 Pending xxxx
1 Submitted xxxy
1 Pending xxxz
, где вы хотите строку для время "xxxz":
с EF6
string pendingStatus = Status.Pending.ToString();
var pending = myContext.TransactionMsg
.Where(x => x.Status == pendingStatus)
.GroupBy(x => x.NodeId)
.Select(g => g.OrderByDescending(x => x.UtcTimestamp).FirstOrDefault())
.ToList();
Теперь я не смог заставить это работать с EF Core (Сюрприз, сюрприз), так что если вы работаете с Core, вы ' Мне нужно будет немного покопаться, чтобы выяснить, как обойти, почему он не может выполнить OrderByDescending
внутри выражения «Выбрать из группы». Еще одна причина придерживаться EF 6:)
Обновление: Хорошо, основано на требовании получить только узлы, на которых ожидается последний статус. Получить это в EF6 было относительно просто, переместив Where
предложение после Select
.
Выполнение этого в EF Core было намного сложнее, но выглядит возможным. Большая проблема в том, как GroupBy
реализован в EF Core. Это намного более ограничено в отношении того, как вы можете взаимодействовать с результатами IGrouping
, где EF6 будет успешно переводить / взаимодействовать с ними как набором, EF Core исключает попытку использовать OrderBy и такие выражения с сгруппированными результатами. Таким образом, вам нужно получить немного больше подробностей:
var results = context.Nodes
.GroupBy(x => x.NodeId, (x,y) => new { Timestamp = y.Max(z => z.Timestamp), NodeId = x })
.Join(context.Nodes, a => new { a.NodeId, a.Timestamp }, b => new { b.NodeId, b.Timestamp }, (a,b) => b)
.Where(g => g.Status == "Pending")
.ToList();
Это действительно выглядит странно, но быстро пройдемся: сначала мы группируем узлы по ID узла, а затем выбираем последнюю метку времени, используя Макс против сгруппированные результаты, чтобы получить наибольшую метку времени, а также выберите идентификатор узла с помощью сгруппированного ключа. Это дает нам структуру { Timestamp (max row), NodeId }
. Используя это, мы Join
возвращаемся к набору узлов, используя сравнение ключей по идентификатору узла и метке времени, чтобы связать выбранные результаты с коллекцией узлов, чтобы мы могли преобразовать эти сгруппированные элементы обратно в сущности узла. Это вернет нам коллекцию узлов, которые соответствуют Node ID и Max Timestamp, то есть «Последние узлы». Исходя из этого, мы применяем предложение Where
, чтобы выбрать только последние узлы, которые находятся в состоянии «Ожидание».