代码之家  ›  专栏  ›  技术社区  ›  Jez

如何使Sum()返回0而不是“null”?

  •  1
  • Jez  · 技术社区  · 6 年前

    我正在尝试使用linqto实体来查询我的数据库,其中有3个表: Room , Conference Participant . 每个房间有许多会议,每个会议有许多参与者。对于每个会议室,我试图计算其会议的数量,以及该会议室所有会议的所有参与者的总数。我的问题是:

    var roomsData = context.Rooms
        .GroupJoin(
            context.Conferences
                .GroupJoin(
                    context.Participants,
                    conf => conf.Id,
                    part => part.ConferenceId,
                    (conf, parts) => new { Conference = conf, ParticipantCount = parts.Count() }
                ),
            rm => rm.Id,
            data => data.Conference.RoomId,
            (rm, confData) => new {
                Room = rm,
                ConferenceCount = confData.Count(),
                ParticipantCount = confData.Sum(cd => cd.ParticipantCount)
            }
        );
    

    当我试着把它变成一个列表时,我得到了一个错误:

    对值类型“System.Int32”的强制转换失败,因为具体化的值为null。结果类型的泛型参数或查询必须使用可为null的类型。

    Sum 行至:

    ParticipantCount = confData.Count() == 0 ? 0 : confData.Sum(cd => cd.ParticipantCount)
    

    但问题是,这似乎会生成更复杂的查询,并在查询时间上增加100ms。有没有更好的方法让我告诉EF当它求和的时候 ParticipantCount ,空列表 confData List<int> 打电话给我 Sum() 在这方面,它给我零,而不是抛出一个例外!

    4 回复  |  直到 6 年前
        1
  •  0
  •   kaffekopp    6 年前

    你可以用 null coalescing operator ?? 作为:

    confData.Sum(cd => cd.ParticipantCount ?? 0)
    
        2
  •  0
  •   Jez    6 年前

    Sum 行至:

    ParticipantCount = (int?)confData.Sum(cd => cd.ParticipantCount)
    

    令人困惑的是,尽管IntelliSense告诉我 int 过载 Sum() 在运行时,它实际上使用 int? confData 列表可能为空。如果我明确告诉它返回类型是 内景? null 对于空的列表条目,我可以稍后使用null合并 是零。

        3
  •  0
  •   adjan    6 年前

    使用 Enumerable.DefaultIfEmpty

     ParticipantCount = confData.DefaultIfEmpty().Sum(cd => cd.ParticipantCount)
    
        4
  •  0
  •   David Browne - Microsoft    6 年前

    不要试图让EF生成返回0而不是null的SQL查询,而是在客户端处理查询结果时更改此值,如下所示:

    var results = from r in roomsData.AsEnumerable()
                  select new 
                  {
                    r.Room,
                    r.ConferenceCount,
                    ParticipantCount = r.ParticipantCount ?? 0
                  };
    

    这个 AsEnumerable()