如果为空查询,则返回最大值

我有这个查询:

int maxShoeSize=Workers.Where(x=>x.CompanyId==8).Max(x=>x.ShoeSize); 

如果公司8根本没有工人,那么maxShoeSize会是什么?

更新:
如何更改查询以获得0而不是exception?

 int maxShoeSize = Workers.Where(x => x.CompanyId == 8) .Select(x => x.ShoeSize) .DefaultIfEmpty(0) .Max(); 

DefaultIfEmpty的零不是必需的。

我知道这是一个老问题,接受的答案是有效的,但是这个问题回答了我这个空集是否会导致exception或default(int)结果的问题。

然而,接受的答案,虽然它的工作,是不是理想的解决scheme恕我直言,这是不是在这里给出。 因此,我正在为自己的答案提供这个答案,以便任何正在寻找答案的人的利益。

OP的原始代码是:

 int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize); 

这是我如何写它来防止exception,并提供一个默认的结果:

 int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize as int?) ?? 0; 

这会导致Max函数的返回types为int? ,它允许null结果,然后??0replacenull结果。

Max()在这种情况下不会返回任何东西。

它将引发InvalidOperationException,因为该源不包含任何元素。

 int maxShoeSize = Workers.Where(x => x.CompanyId == 8) .Select(x => x.ShoeSize) .DefaultIfEmpty() .Max(); 

最大值将抛出System.InvalidOperationException“序列不包含任何元素”

 class Program { static void Main(string[] args) { List<MyClass> list = new List<MyClass>(); list.Add(new MyClass() { Value = 2 }); IEnumerable<MyClass> iterator = list.Where(x => x.Value == 3); // empty iterator. int max = iterator.Max(x => x.Value); // throws System.InvalidOperationException } } class MyClass { public int Value; } 
 int maxShoeSize=Workers.Where(x=>x.CompanyId==8) .Max(x=>(int?)x.ShoeSize).GetValueOrDefault(); 

(假设ShoeSizeinttypes的)

如果Workers是来自entity framework的DbSetObjectSet ,则您的初始查询将引发InvalidOperationException ,但不会抱怨空序列,但抱怨物化值NULL不能转换为int

注意:使用DefaultIfEmpty()的查询可能会明显变慢 。 在我的情况下,这是一个简单的查询与.DefaultIfEmpty(DateTime.Now.Date)

我懒得简介。 但是,显然,EF试图获取所有的行,然后采取Max()值。

结论:有时处理InvalidOperationException可能是更好的select。

你可以在.Max()使用三元来处理谓词并设置它的值。

 // assumes Workers != null && Workers.Count() > 0 int maxShoeSize = Workers.Max(x => (x.CompanyId == 8) ? x.ShoeSize : 0); 

如果可能的话,您需要处理Workers集合为null / empty,但这取决于您的实现。

你可以试试这个:

 int maxShoeSize = Workers.Where(x=>x.CompanyId == 8).Max(x => x.ShoeSize) ?? 0; 

在做Max()之前,你可以检查是否有工人。

 private int FindMaxShoeSize(IList<MyClass> workers) { var workersInCompany = workers.Where(x => x.CompanyId == 8); if(!workersInCompany.Any()) { return 0; } return workersInCompany.Max(x => x.ShoeSize); } 

如果这是Linq to SQL,我不喜欢使用Any(),因为它会导致对SQL Server的多个查询。

如果ShoeSize不是空字段,那么只使用.Max(..) ?? 0 .Max(..) ?? 0将无法正常工作,但会发生以下情况:

 int maxShoeSize = Workers.Where(x = >x.CompanyId == 8).Max(x => (int?)x.ShoeSize) ?? 0; 

它绝对不会改变发出的SQL,但是如果序列是空的,它会返回0,因为它将Max()返回一个int? 而不是一个int。