如果为空查询,则返回最大值
我有这个查询:
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();
(假设ShoeSize是inttypes的)
如果Workers是来自entity framework的DbSet或ObjectSet ,则您的初始查询将引发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。