Чтобы получить максимальное значение столбца, содержащего целое число, я могу использовать следующую команду T-SQL
SELECT MAX(expression )
FROM tables
WHERE predicates;
Можно ли получить такой же результат с Entity Framework.
Допустим, у меня есть следующая модель
public class Person
{
public int PersonID { get; set; }
public int Name { get; set; }
public int Age { get; set; }
}
Как узнать возраст самого старшего человека?
int maxAge = context.Persons.?
c#
sql
entity-framework
max
Ричард77
источник
источник
Если список пуст, я получаю исключение. Это решение учтет эту проблему:
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
источник
await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0
Или вы можете попробовать это:
(From p In context.Persons Select p Order By age Descending).FirstOrDefault
источник
Может быть, поможет, если вы хотите добавить фильтр:
context.Persons .Where(c => c.state == myState) .Select(c => c.age) .DefaultIfEmpty(0) .Max();
источник
maxAge = Persons.Max(c => c.age)
Или что-то вдоль этих линий.
источник
Ваш столбец допускает значение NULL
int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;
Ваш столбец не допускает значения NULL
int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;
В обоих случаях вы можете использовать второй код. Если вы используете
DefaultIfEmpty
, вы будете делать больший запрос на своем сервере. Для тех, кому интересно, вот эквивалент EF6:Запрос без
DefaultIfEmpty
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Extent1].[Age]) AS [A1] FROM [dbo].[Persons] AS [Extent1] ) AS [GroupBy1]
Запрос с
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]
источник
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
Как многие говорили - эта версия
int maxAge = context.Persons.Max(p => p.Age);
выдает исключение, когда таблица пуста.
Использовать
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
или
int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()
источник
В VB.Net это было бы
Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)
источник
int maxAge = context.Persons.Max(p => p.Age);
Эта версия, если список пуст :
null
- для перегрузок, допускающих значение NULLSequence contains no element
исключение - для перегрузок, не допускающих значения NULL-
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
Эта версия обрабатывает случай пустого списка, но генерирует более сложный запрос и по какой-то причине не работает с EF Core.
-
int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0;
Эта версия элегантна и производительна (простой запрос и одно обращение к базе данных), работает с EF Core. Он обрабатывает упомянутое выше исключение, преобразуя тип, не допускающий значение NULL, к типу, допускающему значение NULL, а затем применяет значение по умолчанию с помощью
??
оператора.источник
Выбранный ответ вызывает исключения, а ответ Карлоса Толедо применяет фильтрацию после извлечения всех значений из базы данных.
Следующий запускает один цикл и считывает одно значение с использованием любых возможных индексов без исключения.
int maxAge = _dbContext.Persons .OrderByDescending(p => p.Age) .Select(p => p.Age) .FirstOrDefault();
источник