huc*_*ius 5 c# asp.net entity-framework asp.net-core
我在ASP核心API项目中使用ef核心。我必须找到最高顺序的索引。
例:
数据表: Id, ForeignId, OrderIndex
所以我在做:
var highestOrderIndex = await _context
.ExampleDbSet
.Where(x =>
x.ForeignId == foreignId)
.MaxAsync(x =>
x.OrderIndex);
Run Code Online (Sandbox Code Playgroud)
问题是示例数据库集包含0个元素时。这将引发异常:Sequence contains no element。
有没有一种优雅的方法可以做到这一点?因为我不想从数据库中获取所有元素。而且应该是异步的。
谢谢
Iva*_*oev 16
实际上,通过利用像这样的聚合方法Min,仅当与不可为空的重载一起使用时才Max抛出Sequence contains no element异常,而实际上可以为空的重载,是一种相当优雅的方法(与其他答案中建议的相比,性能更高,因为它只执行一个数据库查询)返回null。
因此,您所需要做的就是将不可为空的属性类型提升为相应的可为空类型。例如,如果OrderIndex类型为int,则对查询的唯一更改可能是
.MaxAsync(x => (int?)x.OrderIndex);
Run Code Online (Sandbox Code Playgroud)
请注意,这还会将接收变量的类型更改highestOrderIndex为int?。您可以检查null并做出相应的反应,或者可以简单地将聚合函数调用与??运算符结合起来并提供一些默认值,例如
var highestOrderIndex = (await _context.ExampleDbSet
.Where(x => x.ForeignId == foreignId)
.MaxAsync(x => (int?)x.OrderIndex)) ?? -1; // or whatever "magic" number works for you
Run Code Online (Sandbox Code Playgroud)
MaxAsync如果默认值是您想要获得的值,并且没有结果,则另一种性能比 更好的方法:
var highestOrderIndex = await _context.ExampleDbSet
.Where(x => x.ForeignId == foreignId)
.OrderByDescending(x => x.OrderIndex)
.Select(x => x.OrderIndex)
.FirstOrDefaultAsync();
Run Code Online (Sandbox Code Playgroud)
TOP比聚合函数更快,查看 SQL Server 中的执行计划。
执行 anAnyAsync和 aMaxAsync将导致两个单独的数据库调用。您可以通过确保序列包含“默认”最小值来将其压缩为一个。在任何使用 Linq Max/Min 方法的地方,这都是一个有用的技巧,而不仅仅是在数据库代码中:
context.ExampleDbSet
.Where(w => w.ForeignId == foreignId)
.Select(s => s.OrderIndex)
.Concat(new[] { 0 })
.MaxAsync();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1015 次 |
| 最近记录: |