如何使用实体框架获得列的最大值?

要获得包含整数的列的最大值,可以使用以下 T-SQL 命令

SELECT MAX(expression )
FROM tables
WHERE predicates;

Is it possible to obtain the same result with Entity Framework.

假设我有以下模型

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

How do I get the oldest person's age?

int maxAge = context.Persons.?
167460 次浏览

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

And make sure you have using System.Linq; at the top of your file

maxAge = Persons.Max(c => c.age)

or something along those lines.

或者你可以试试这个:

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

In VB.Net it would be

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

如果列表是空的,我会得到一个异常。这个解决方案会考虑到这个问题:

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

也许有帮助,如果你想添加一些过滤器:

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

就像很多人说的,这个版本

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()

选定的答案会抛出异常,Carlos Toledo 的答案在从数据库中检索所有值之后应用筛选。

下面的代码运行单个往返并使用任何可能的索引读取单个值,没有任何异常。

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

你的专栏可以为空

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

你的专栏是不可取消的

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(p => p.Age);

The version above, 如果列表为空:

  • 返回 null-用于可为空的重载
  • 引发 Sequence contains no element异常-用于不可为空的重载

我不知道

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

The version above handles the empty list case, but it generates more complex query, and for some reason doesn't work with EF Core.

_

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

这个版本是 优雅表演者(简单的查询和到数据库的单一往返) ,works with EF Core。它通过将非空类型强制转换为空值,然后使用 ??运算符应用默认值来处理上面提到的异常。