wake-up-neo.net

Wie erhalte ich den maximalen Wert einer Spalte mit Entity Framework?

Um den maximalen Wert einer Spalte zu erhalten, die eine Ganzzahl enthält, kann ich den folgenden T-SQL-Befehl verwenden

SELECT MAX(expression )
FROM tables
WHERE predicates;

Ist es möglich, mit Entity Framework dasselbe Ergebnis zu erzielen.

Nehmen wir an, ich habe folgendes Modell

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

Wie bekomme ich das Alter der ältesten Person?

int maxAge = context.Persons.?
66
Richard77

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

Stellen Sie sicher, dass Sie using System.Linq; oben in Ihrer Datei haben

114
krolik

Wenn die Liste leer ist, bekomme ich eine Ausnahme. Diese Lösung berücksichtigt dieses Problem:

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

Oder du kannst es versuchen:

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

Vielleicht helfen, wenn Sie einen Filter hinzufügen möchten:

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

oder etwas in diese Richtung.

5
E.J. Brennan

In VB.Net wäre es 

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

Wie viele sagten - diese Version

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

löst eine Ausnahme aus, wenn die Tabelle leer ist.

Benutzen

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

oder

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

Ihre Spalte ist nullbar

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

Ihre Spalte ist nicht nullbar

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

In beiden Fällen können Sie den zweiten Code verwenden. Wenn Sie DefaultIfEmpty verwenden, werden Sie eine größere Abfrage auf Ihrem Server durchführen. Für Interessierte gibt es hier das EF6-Äquivalent:

Abfrage ohne DefaultIfEmpty

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

Abfrage mit 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

Die ausgewählte Antwort löst Ausnahmen aus, und die Antwort von Carlos Toledo wendet eine Filterung an, nachdem alle Werte aus der Datenbank abgerufen wurden.

Der folgende führt einen einzelnen Roundtrip aus und liest ausnahmslos einen einzelnen Wert unter Verwendung möglicher Indizes.

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