如何强制LINQ Sum()在源集合为空时返回0

基本上,当我做下面的查询时,如果没有线索匹配下面的查询会引发exception。 在这种情况下,我宁愿总和均衡为0,而不是引发exception。 这是可能的查询本身 – 我的意思是而不是存储查询和检查query.Any()

 double earnings = db.Leads.Where(l => l.Date.Day == date.Day && l.Date.Month == date.Month && l.Date.Year == date.Year && l.Property.Type == ProtectedPropertyType.Password && l.Property.PropertyId == PropertyId).Sum(l => l.Amount); 

尝试将您的查询更改为:

 db.Leads.Where(l => l.Date.Day == date.Day && l.Date.Month == date.Month && l.Date.Year == date.Year && l.Property.Type == ProtectedPropertyType.Password && l.Property.PropertyId == PropertyId) .Select(l => l.Amount) .DefaultIfEmpty(0) .Sum(); 

这样,您的查询将只selectAmount字段。 如果集合是空的,它将返回一个值为0元素,然后总和将被应用。

我更喜欢使用另一个黑客:

 double earnings = db.Leads.Where(l => l.Date.Day == date.Day && l.Date.Month == date.Month && l.Date.Year == date.Year && l.Property.Type == ProtectedPropertyType.Password && l.Property.PropertyId == PropertyId) .Sum(l => (double?) l.Amount) ?? 0; 

试试这个,它更短:

 db.Leads.Where(..).Aggregate(0, (i, lead) => i + lead.Amount); 
 db.Leads.Where(l => l.Date.Day == date.Day && l.Date.Month == date.Month && l.Date.Year == date.Year && l.Property.Type == ProtectedPropertyType.Password && l.Property.PropertyId == PropertyId) .Select(l => l.Amount) .ToList() .Sum(); 

更新:虽然工作的解决scheme, 这个答案是不正确的 。 显然,正确的是西蒙·贝兰杰(Simon Belanger)给出的。 尽pipe如此,我并没有删除这些信息作为补充信息(见评论)。

这里有趣的细节是LINQ To SQL实现Sum (这个你明显使用) 不同于LINQ To Objects之一。 西蒙Belanger答案是正确的,我喜欢它,但(不要远远地search)另一个选项,使这个工作是改变编译types的源和LINQ到对象的使用。 不同的Sum将被执行(不需要任何额外的操作):

 db.Leads.Where(...) .AsEnumerable() // switch to LINQ to Objects .Sum(l => l.Amount); 

来自MSDN :

除了将源的编译时types从实现IEnumerable的types改为IEnumerable本身之外,AsEnumerable(IEnumerable)方法没有效果。