En esta consulta:
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());
}
Tuve que cambiarlo a esto para que funcione
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());
}
Ni siquiera podía usar p.First()
, para reflejar la primera consulta.
¿Por qué hay limitaciones tan básicas en lo que de otro modo es un sistema ORM tan robusto?
c#
entity-framework
orm
bevacqua
fuente
fuente
Respuestas:
Esa limitación se reduce al hecho de que eventualmente tiene que traducir esa consulta a SQL y SQL tiene un
SELECT TOP
(en T-SQL) pero no unSELECT BOTTOM
(no existe).Sin embargo, hay una manera fácil de evitarlo, solo ordena descender y luego haz un
First()
, que es lo que hiciste.EDITAR: Otros proveedores posiblemente tendrán implementaciones diferentes de
SELECT TOP 1
, en Oracle probablemente sería algo más comoWHERE ROWNUM = 1
EDITAR:
Otra alternativa menos eficiente: ¡NO lo recomiendo! - es llamar
.ToList()
a sus datos antes.Last()
, lo que ejecutará inmediatamente la expresión LINQ To Entities que se ha construido hasta ese punto, y luego su .Last () funcionará, porque en ese punto.Last()
se ejecuta efectivamente en el contexto de un LINQ to Objects Expression en su lugar. (Y como señaló, podría recuperar miles de registros y desperdiciar cargas de objetos de materialización de CPU que nunca se usarán)Nuevamente, no recomendaría hacer este segundo, pero ayuda a ilustrar la diferencia entre dónde y cuándo se ejecuta la expresión LINQ.
fuente
ToList
no es tan malo.En lugar de
Last()
, intente esto:fuente
Reemplazar
Last()
por un selector LinqOrderByDescending(x => x.ID).Take(1).Single()
Algo así funcionaría si lo prefieres hacerlo en Linq:
fuente
Otra forma de obtener el último elemento sin OrderByDescending y cargar todas las entidades:
fuente
Esto se debe a que LINQ to Entities (y las bases de datos en general) no es compatible con todos los métodos LINQ (consulte aquí para más detalles: http://msdn.microsoft.com/en-us/library/bb738550.aspx )
Lo que necesita aquí es ordenar sus datos de tal manera que el "último" registro se convierta en "primero" y luego pueda usar FirstOrDefault. Tenga en cuenta que databasese generalmente no tiene conceptos como "primero" y "último", no es como si el registro insertado más recientemente fuera "último" en la tabla.
Este método puede resolver tu problema
fuente
Agregar una sola función
AsEnumerable()
antes de Seleccionar me funcionó.Ejemplo:
Ref: https://www.codeproject.com/Questions/1005274/LINQ-to-Entities-does-not-recognize-the-method-Sys
fuente