Aby uzyskać maksymalną wartość kolumny zawierającej liczbę całkowitą, mogę użyć następującego polecenia T-SQL
SELECT MAX(expression )
FROM tables
WHERE predicates;
Czy można uzyskać ten sam wynik w Entity Framework.
Powiedzmy, że mam następujący model
public class Person
{
public int PersonID { get; set; }
public int Name { get; set; }
public int Age { get; set; }
}
Jak określić wiek najstarszej osoby?
int maxAge = context.Persons.?
c#
sql
entity-framework
max
Richard77
źródło
źródło
Jeśli lista jest pusta, pojawia się wyjątek. To rozwiązanie uwzględni ten problem:
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
źródło
await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0
Lub możesz spróbować tego:
(From p In context.Persons Select p Order By age Descending).FirstOrDefault
źródło
Może pomóż, jeśli chcesz dodać jakiś filtr:
context.Persons .Where(c => c.state == myState) .Select(c => c.age) .DefaultIfEmpty(0) .Max();
źródło
maxAge = Persons.Max(c => c.age)
czy coś podobnego.
źródło
Twoja kolumna ma wartość null
int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;
Twoja kolumna nie dopuszcza wartości null
int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;
W obu przypadkach możesz użyć drugiego kodu. Jeśli używasz
DefaultIfEmpty
, wykonasz większe zapytanie na swoim serwerze. Dla zainteresowanych, oto odpowiednik EF6:Zapytanie bez
DefaultIfEmpty
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Extent1].[Age]) AS [A1] FROM [dbo].[Persons] AS [Extent1] ) AS [GroupBy1]
Zapytanie z
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]
źródło
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
Jak wielu powiedziało - ta wersja
int maxAge = context.Persons.Max(p => p.Age);
zgłasza wyjątek, gdy tabela jest pusta.
Posługiwać się
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
lub
int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()
źródło
W VB.Net byłoby
Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)
źródło
int maxAge = context.Persons.Max(p => p.Age);
Ta wersja, jeśli lista jest pusta :
null
- dla przeciążeń dopuszczających wartość nullSequence contains no element
wyjątek - dla przeciążeń niepodlegających wartości null-
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
Ta wersja obsługuje pusty przypadek listy, ale generuje bardziej złożone zapytanie iz jakiegoś powodu nie działa z EF Core.
-
int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0;
Ta wersja jest elegancka i wydajna (proste zapytanie i pojedyncza runda do bazy danych), współpracuje z EF Core. Obsługuje wspomniany wyjątek powyżej, rzutując typ niedopuszczający wartości null do wartości null, a następnie stosując wartość domyślną przy użyciu
??
operatora.źródło
Wybrana odpowiedź generuje wyjątki, a odpowiedź od Carlosa Toledo stosuje filtrowanie po pobraniu wszystkich wartości z bazy danych.
Poniższy uruchamia pojedynczą podróż w obie strony i odczytuje pojedynczą wartość przy użyciu dowolnych możliwych indeksów bez wyjątku.
int maxAge = _dbContext.Persons .OrderByDescending(p => p.Age) .Select(p => p.Age) .FirstOrDefault();
źródło