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) ?? 0O puedes probar esto:
(From p In context.Persons Select p Order By age Descending).FirstOrDefaultfuente
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
DefaultIfEmptySELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Extent1].[Age]) AS [A1] FROM [dbo].[Persons] AS [Extent1] ) AS [GroupBy1]Consulta con
DefaultIfEmptySELECT [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 elementexcepció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