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

Joh*_*yer 169 .net c# entity-framework

基本上,当我执行以下查询时,如果没有匹配的引导,则以下查询将引发异常.在那种情况下,我宁愿将总和等于0而不是抛出异常.这可能在查询本身 - 我的意思是,而不是存储查询和检查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);
Run Code Online (Sandbox Code Playgroud)

Sim*_*ger 362

尝试将您的查询更改为:

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();
Run Code Online (Sandbox Code Playgroud)

这样,您的查询将只选择该Amount字段.如果集合为空,它将返回一个值为的元素,0然后将应用总和.

  • 要知道,'DefaultIfEmpty`不是由一些LINQ提供的支持,所以你需要在`ToList(投)'或类似的东西之前,在这些情况下使用它,这样它会在*LINQ应用到对象*场景. (5认同)
  • @MaksimVI EF将在第一次实现时生成查询,当`IQueryable <T>`链停止时(通常当你调用`ToList`,`AsEnumerable`等等......在这种情况下是`Sum`).`Sum`是EF可查询提供程序的已知和处理方法,它将生成相关的SQL语句. (3认同)
  • @SimonBelanger 我更正了,总和是在数据库端进行的,但它是在首先选择金额的子查询上进行的。基本上查询是`SELECT SUM(a.Amount) FROM (SELECT Amount FROM Leads WHERE ...) AS a` 而不仅仅是`SELECT SUM(Amount) FROM Leads`。此外,子查询还有一个额外的空检查和一个带有单行表的奇怪外连接。 (2认同)

tuk*_*aef 171

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

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;
Run Code Online (Sandbox Code Playgroud)

  • 使用Linq to SQL时,这会生成比接受的答案短得多的SQL代码 (15认同)
  • 这是正确的答案.所有其他人都失败 首先转换为可空,然后将最终结果与null进行比较. (3认同)
  • 这比Linq To EF的接受答案要好得多.对我来说,生成的SQL比DefaultIfEmpty好大约3.8倍. (3认同)
  • 这是更快. (2认同)

Kov*_*ert 5

试试这个,它更短:

db.Leads.Where(..).Aggregate(0, (i, lead) => i + lead.Amount);
Run Code Online (Sandbox Code Playgroud)

  • 短?也许......但绝对不清楚. (5认同)
  • 这是否避免了异常? (2认同)