如果为空查询,则返回最大值
我有这个查询:
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
结果,然后??
用0
replacenull
结果。
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
是int
types的)
如果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。