Skip to main content
 首页 » 编程设计

c#之如何合并 .Max() 以查询 LINQ to EF 中的空集合

2024年05月22日36shihaiming

我的模型中有一个具有整数属性的实体:

public class Foo 
{ 
    public int SortOrder { get; set; } 
 
    // ...other props 
} 

现在,对于数据库中所有 Foo 的某些子集,我想选择最高的 SortOrder 并添加一个 - 即获取新的排序顺序最后添加到集合中的对象 - 但如果该子集中没有 Foo,我想以 0 结尾 - 即添加到空集合中的新对象的排序顺序。

阅读 this reference page ,我得到的印象是,如果它聚合的集合为空,则 .Max() 返回 null,因此我尝试了以下操作:

var sortOrder = context.Foos 
    .Where(/* predicate for subset */) 
    .Max(foo => foo.SortOrder) + 1 
    ?? 0; 

但这不会编译,因为 .Max 的返回类型被推断为 int,不能为 null 合并。

但是,如果我不使用 null 合并,并假设 .Max() 确实返回 default(T)(即 0 在这种情况下),那么我将以 1 而不是 0 作为空案例的结尾。由于这是对数据库的调用,我宁愿凑合使用一个查询。

如果我将 Foo 上的属性设为 int? 类型,它会按照我想要的方式工作,但我不想这样做,因为我们不允许在数据库中使用 NULL 值,我认为没有理由在实体上允许它们。

请您参考如下方法:

I got the impression that .Max() returns null if the collection over which it aggregates is empty

您得到一个 InvalidOperationException 记录在案 here

“InvalidOperationException...源不包含任何元素。”

您可以使用 DefaultIfEmpty(0) :

int maxSortOrder = context.Foos 
    .Where(/* predicate for subset */) 
    .Select(foo => foo.SortOrder + 1) 
    .DefaultIfEmpty(0) 
    .Max();