Para obter o valor máximo de uma coluna que contém um inteiro, posso usar o seguinte comando T-SQL
SELECT MAX(expression )
FROM tables
WHERE predicates;
É possível obter o mesmo resultado com Entity Framework.
Digamos que tenho o seguinte modelo
public class Person
{
public int PersonID { get; set; }
public int Name { get; set; }
public int Age { get; set; }
}
Como faço para saber a idade da pessoa mais velha?
int maxAge = context.Persons.?
c#
sql
entity-framework
max
Richard77
fonte
fonte
Se a lista estiver vazia, recebo uma exceção. Esta solução levará em consideração este problema:
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
fonte
await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0
Ou você pode tentar isto:
(From p In context.Persons Select p Order By age Descending).FirstOrDefault
fonte
Talvez ajude, se você quiser adicionar algum filtro:
context.Persons .Where(c => c.state == myState) .Select(c => c.age) .DefaultIfEmpty(0) .Max();
fonte
maxAge = Persons.Max(c => c.age)
Ou algo nesse sentido.
fonte
Sua coluna é anulável
int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;
Sua coluna não é anulável
int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;
Em ambos os casos, você pode usar o segundo código. Se você usar
DefaultIfEmpty
, fará uma consulta maior no seu servidor. Para as pessoas interessadas, aqui estão os equivalentes EF6:Consulta sem
DefaultIfEmpty
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Extent1].[Age]) AS [A1] FROM [dbo].[Persons] AS [Extent1] ) AS [GroupBy1]
Consultar com
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]
fonte
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
Como muitos disseram - esta versão
int maxAge = context.Persons.Max(p => p.Age);
lança uma exceção quando a tabela está vazia.
Usar
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
ou
int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()
fonte
Em VB.Net seria
Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)
fonte
int maxAge = context.Persons.Max(p => p.Age);
Esta versão, se a lista estiver vazia :
null
- para sobrecargas anuláveisSequence contains no element
exceção - para sobrecargas não anuláveis-
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
Esta versão lida com o caso de lista vazia, mas gera uma consulta mais complexa e, por algum motivo, não funciona com EF Core.
-
int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0;
Esta versão é elegante e eficiente (consulta simples e ida e volta ao banco de dados), funciona com EF Core. Ele lida com a exceção mencionada acima convertendo o tipo não anulável em anulável e, em seguida, aplicando o valor padrão usando o
??
operador.fonte
A resposta selecionada gera exceções, e a resposta de Carlos Toledo aplica a filtragem após recuperar todos os valores do banco de dados.
O seguinte executa uma única viagem de ida e volta e lê um único valor, usando qualquer índice possível, sem exceção.
int maxAge = _dbContext.Persons .OrderByDescending(p => p.Age) .Select(p => p.Age) .FirstOrDefault();
fonte