web-dev-qa-db-fra.com

Comment obtenir la valeur maximale d'une colonne en utilisant Entity Framework?

Pour obtenir la valeur maximale d'une colonne contenant un entier, je peux utiliser la commande T-SQL suivante

SELECT MAX(expression )
FROM tables
WHERE predicates;

Est-il possible d'obtenir le même résultat avec Entity Framework.

Disons que j'ai le modèle suivant

public class Person
{
  public int PersonID { get; set; }
  public int Name { get; set; }
  public int Age { get; set; }
}

Comment puis-je obtenir l'âge de la personne la plus âgée?

int maxAge = context.Persons.?
66
Richard77

Essayez ceci int maxAge = context.Persons.Max(p => p.Age);

Et assurez-vous d'avoir using System.Linq; en haut de votre fichier

114
krolik

Si la liste est vide, je reçois une exception. Cette solution prendra en compte ce problème:

int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
31
Carlos Toledo

Ou vous pouvez essayer ceci:

(From p In context.Persons Select p Order By age Descending).FirstOrDefault
8
danicode

Peut-être aidez-vous si vous voulez ajouter un filtre:

context.Persons
.Where(c => c.state == myState)
.Select(c => c.age)
.DefaultIfEmpty(0)
.Max();
5
Foy
maxAge = Persons.Max(c => c.age)

ou quelque chose du genre.

5
E.J. Brennan

Dans VB.Net ce serait 

Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)
2
dipi evil

Comme beaucoup l'ont dit - cette version

int maxAge = context.Persons.Max(p => p.Age);

lève une exception lorsque la table est vide.

Utilisation

int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;

ou

int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()
1
A K

Votre colonne est nullable

int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;

Votre colonne est non nullable

int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;

Dans les deux cas, vous pouvez utiliser le deuxième code. Si vous utilisez DefaultIfEmpty, vous ferez une requête plus grosse sur votre serveur. Pour les personnes intéressées, voici l'équivalent EF6:

Requête sans DefaultIfEmpty

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        MAX([Extent1].[Age]) AS [A1]
        FROM [dbo].[Persons] AS [Extent1]
    )  AS [GroupBy1]

Requête avec 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]
0
jsgoupil

La réponse sélectionnée lève des exceptions et la réponse de Carlos Toledo applique le filtrage après avoir extrait toutes les valeurs de la base de données.

Le suivant exécute un aller-retour unique et lit une seule valeur, en utilisant tous les index possibles, sans exception.

int maxAge = _dbContext.Persons
  .OrderByDescending(p => p.Age)
  .Select(p => p.Age)
  .FirstOrDefault();
0
SuperDuck