如何使用Entity Framework获取列的最大值?

Ric*_*d77 79 c# sql entity-framework max

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

SELECT MAX(expression )
FROM tables
WHERE predicates;
Run Code Online (Sandbox Code Playgroud)

是否可以使用Entity Framework获得相同的结果.

假设我有以下型号

public class Person
{
  public int PersonID { get; set; }
  public int Name { get; set; }
  public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我如何获得最老的人的年龄?

int maxAge = context.Persons.?
Run Code Online (Sandbox Code Playgroud)

kro*_*lik 135

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

并确保您using System.Linq;位于文件的顶部

  • 我对此有点挣扎,因为我错过了“使用 System.Linq;” 您应该考虑将该信息添加到您对像我这样的新手的回答中:) (3认同)
  • 但是如果你没有任何记录和EF拖欠错误怎么办?我的加法var model = db.BillOfLading.Select(x => x.No).LastOrDefault(); if(model!= null){var val = db.BillOfLading.Max(x => x.No); (3认同)
  • 没问题@RagnaRock (2认同)
  • 适合 EF Core 中的异步:await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0 (2认同)

Car*_*edo 42

如果列表为空,我会得到一个例外.此解决方案将考虑此问题:

int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案.只有一次往返服务器,没有例外. (7认同)
  • 但它从数据库中检索所有列值,并在应用程序端应用 Max。 (5认同)
  • 只是一个旁注 - 这不适用于 EF core。我用过:`await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0` (5认同)
  • 这产生了 3 个子查询。我提出了不同的答案。 (2认同)

dan*_*ode 9

或者你可以尝试这个:

(From p In context.Persons Select p Order By age Descending).FirstOrDefault
Run Code Online (Sandbox Code Playgroud)


jsg*_*pil 7

您的列可以为空

int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;
Run Code Online (Sandbox Code Playgroud)

您的列不可为空

int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,您都可以使用第二个代码。如果您使用DefaultIfEmpty,您将在您的服务器上进行更大的查询。对于感兴趣的人,以下是 EF6 等效项:

查询没有 DefaultIfEmpty

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        MAX([Extent1].[Age]) AS [A1]
        FROM [dbo].[Persons] AS [Extent1]
    )  AS [GroupBy1]
Run Code Online (Sandbox Code Playgroud)

查询 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]
Run Code Online (Sandbox Code Playgroud)

  • `int maxAge = context.Persons.Max(x =&gt; (int?)x.Age) 怎么样?0;` (2认同)

小智 6

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

context.Persons
.Where(c => c.state == myState)
.Select(c => c.age)
.DefaultIfEmpty(0)
.Max();
Run Code Online (Sandbox Code Playgroud)


E.J*_*nan 5

maxAge = Persons.Max(c => c.age)
Run Code Online (Sandbox Code Playgroud)

或类似的规定.


A K*_*A K 5

正如很多人所说 - 这个版本

int maxAge = context.Persons.Max(p => p.Age);
Run Code Online (Sandbox Code Playgroud)

当表为空时抛出异常。

使用

int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
Run Code Online (Sandbox Code Playgroud)

或者

int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()
Run Code Online (Sandbox Code Playgroud)


Sup*_*uck 5

选定的答案会引发异常,而 Carlos Toledo 的答案会在从数据库中检索所有值后应用过滤。

下面的例子运行一次往返并读取单个值,使用任何可能的索引,没有例外。

int maxAge = _dbContext.Persons
  .OrderByDescending(p => p.Age)
  .Select(p => p.Age)
  .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)


Sei*_*vic 5

int maxAge = context.Persons.Max(p => p.Age); 
Run Code Online (Sandbox Code Playgroud)

上面的版本,如果列表为空

  • 返回null? 对于可为空的重载
  • 抛出Sequence contains no element异常?对于不可为空的重载

_

int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max(); 
Run Code Online (Sandbox Code Playgroud)

上面的版本处理空列表情况,但它生成更复杂的查询,并且由于某种原因不适用于 EF Core。

_

int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0; 
Run Code Online (Sandbox Code Playgroud)

此版本优雅高性能(简单查询和数据库单次往返),可与 EF Core 配合使用。它通过将不可空类型转换为可空类型,然后使用??运算符应用默认值来处理上面提到的异常。