Para obtener el valor máximo de una columna que contiene un número entero, puedo usar el siguiente comando T-SQL
SELECT MAX(expression )
FROM tables
WHERE predicates;
¿Es posible obtener el mismo resultado con Entity Framework?
Digamos que tengo el siguiente modelo
public class Person
{
public int PersonID { get; set; }
public int Name { get; set; }
public int Age { get; set; }
}
¿Cómo obtengo la edad de la persona mayor?
int maxAge = context.Persons.?
c#
sql
entity-framework
max
Richard77
fuente
fuente
Si la lista está vacía, obtengo una excepción. Esta solución tendrá en cuenta este problema:
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
fuente
await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0
O puedes probar esto:
(From p In context.Persons Select p Order By age Descending).FirstOrDefault
fuente
Tal vez ayude, si desea agregar algún filtro:
context.Persons .Where(c => c.state == myState) .Select(c => c.age) .DefaultIfEmpty(0) .Max();
fuente
maxAge = Persons.Max(c => c.age)
O algo por el estilo.
fuente
Tu columna es anulable
int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;
Tu columna no admite nulos
int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;
En ambos casos, puede utilizar el segundo código. Si utiliza
DefaultIfEmpty
, hará una consulta más grande en su servidor. Para las personas que estén interesadas, aquí está el equivalente EF6:Consulta sin
DefaultIfEmpty
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Extent1].[Age]) AS [A1] FROM [dbo].[Persons] AS [Extent1] ) AS [GroupBy1]
Consulta con
DefaultIfEmpty
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Join1].[A1]) AS [A1] FROM ( SELECT CASE WHEN ([Project1].[C1] IS NULL) THEN 0 ELSE [Project1].[Age] END AS [A1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1] LEFT OUTER JOIN (SELECT [Extent1].[Age] AS [Age], cast(1 as tinyint) AS [C1] FROM [dbo].[Persons] AS [Extent1]) AS [Project1] ON 1 = 1 ) AS [Join1] ) AS [GroupBy1]
fuente
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
Como muchos dijeron, esta versión
int maxAge = context.Persons.Max(p => p.Age);
lanza una excepción cuando la tabla está vacía.
Utilizar
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
o
int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()
fuente
En VB.Net sería
Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)
fuente
int maxAge = context.Persons.Max(p => p.Age);
Esta versión, si la lista está vacía :
null
: para sobrecargas que valores NULLSequence contains no element
excepción: para sobrecargas que no aceptan valores NULL-
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
Esta versión maneja el caso de lista vacía, pero genera consultas más complejas y, por alguna razón, no funciona con EF Core.
-
int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0;
Esta versión es elegante y eficiente (consulta simple y ida y vuelta a la base de datos), funciona con EF Core. Maneja la excepción mencionada anteriormente convirtiendo el tipo no anulable en anulable y luego aplicando el valor predeterminado usando el
??
operador.fuente
La respuesta seleccionada arroja excepciones y la respuesta de Carlos Toledo aplica filtrado después de recuperar todos los valores de la base de datos.
El siguiente ejecuta un solo viaje de ida y vuelta y lee un solo valor, utilizando cualquier índice posible, sin excepción.
int maxAge = _dbContext.Persons .OrderByDescending(p => p.Age) .Select(p => p.Age) .FirstOrDefault();
fuente