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 obtenir l'âge de la personne la plus âgée?
int maxAge = context.Persons.?
c#
sql
entity-framework
max
Richard77
la source
la source
Si la liste est vide, j'obtiens une exception. Cette solution prendra en compte ce problème:
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
la source
await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0
Ou vous pouvez essayer ceci:
(From p In context.Persons Select p Order By age Descending).FirstOrDefault
la source
Peut-être aider, si vous souhaitez ajouter un filtre:
context.Persons .Where(c => c.state == myState) .Select(c => c.age) .DefaultIfEmpty(0) .Max();
la source
maxAge = Persons.Max(c => c.age)
Ou quelque chose de ce genre.
la source
Votre colonne est nullable
int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;
Votre colonne n'est pas 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 importante 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]
la source
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
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()
la source
Dans VB.Net, ce serait
Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)
la source
int maxAge = context.Persons.Max(p => p.Age);
Cette version, si la liste est vide :
null
- pour les surcharges NullableSequence contains no element
exception - pour les surcharges non nulles-
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
Cette version gère la casse de liste vide, mais elle génère une requête plus complexe et, pour une raison quelconque, ne fonctionne pas avec EF Core.
-
int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0;
Cette version est élégante et performante (requête simple et aller-retour unique vers la base de données), fonctionne avec EF Core. Il gère l'exception mentionnée ci-dessus en convertissant le type non nullable en nullable, puis en appliquant la valeur par défaut à l'aide de l'
??
opérateur.la source
La réponse sélectionnée lève des exceptions et la réponse de Carlos Toledo applique le filtrage après avoir récupéré toutes les valeurs de la base de données.
Le suivant exécute un seul aller-retour 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();
la source