В этом запросе:
public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
var context = DataContext.GetDataContext();
return context.ServerOnlineCharacters
.OrderBy(p => p.ServerStatus.ServerDateTime)
.GroupBy(p => p.RawName)
.Select(p => p.Last());
}
Я должен был переключиться на это, чтобы он работал
public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
var context = DataContext.GetDataContext();
return context.ServerOnlineCharacters
.OrderByDescending(p => p.ServerStatus.ServerDateTime)
.GroupBy(p => p.RawName)
.Select(p => p.FirstOrDefault());
}
Я даже не мог использовать p.First()
, чтобы отразить первый запрос.
Почему существуют такие основные ограничения в том, что в противном случае такая надежная система ORM?
c#
entity-framework
orm
bevacqua
источник
источник
Ответы:
Это ограничение сводится к тому, что в конечном итоге он должен перевести этот запрос в SQL, а SQL имеет
SELECT TOP
(в T-SQL), но неSELECT BOTTOM
(нет).Хотя есть простой способ обойти это, просто заказать по убыванию, а затем сделать
First()
, что вы и сделали.РЕДАКТИРОВАТЬ: Другие поставщики, возможно, будут иметь различные реализации
SELECT TOP 1
, на Oracle это, вероятно, будет что-то вродеWHERE ROWNUM = 1
РЕДАКТИРОВАТЬ:
Еще одна менее эффективная альтернатива - я НЕ рекомендую это! - это вызвать
.ToList()
ваши данные раньше.Last()
, что немедленно выполнит выражение LINQ To Entities, которое было построено до этого момента, а затем ваш .Last () будет работать, потому что в этот момент.Last()
он эффективно выполняется в контексте LINQ to Objects Expression вместо этого. (И, как вы указали, это может привести к тысячам записей и ненужной загрузке материализационных объектов ЦП, которые никогда не будут использованы)Опять же, я бы не рекомендовал делать эту секунду, но это помогает проиллюстрировать разницу между тем, где и когда выполняется выражение LINQ.
источник
ToList
не так уж и плох.Вместо этого
Last()
попробуйте это:источник
Заменить
Last()
селектором LinqOrderByDescending(x => x.ID).Take(1).Single()
Нечто подобное будет работать, если вы предпочитаете делать это в Linq:
источник
Еще один способ получить последний элемент без OrderByDescending и загрузить все объекты:
источник
Это связано с тем, что LINQ to Entities (и базы данных в целом) не поддерживает все методы LINQ (подробности см. Здесь: http://msdn.microsoft.com/en-us/library/bb738550.aspx ).
Здесь вам нужно упорядочить данные таким образом, чтобы «последняя» запись стала «первой», а затем вы можете использовать FirstOrDefault. Обратите внимание, что базы данных обычно не имеют таких понятий, как «первый» и «последний», это не значит, что последняя вставленная запись будет «последней» в таблице.
Этот метод может решить вашу проблему
источник
Добавление одной функции
AsEnumerable()
до выбора функции работало для меня.Пример:
Ссылка: https://www.codeproject.com/Questions/1005274/LINQ-to-Entities-does-not-recognize-the-method-Sys
источник