[英]How can I make Sum() return 0 instead of 'null'?
我正在尝试使用LINQ-to-entities查询我的数据库,其中有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。 结果类型的通用参数或查询必须使用可为空的类型。
我可以通过将“ Sum
行更改为:
ParticipantCount = confData.Count() == 0 ? 0 : confData.Sum(cd => cd.ParticipantCount)
但麻烦的是,这似乎会生成更复杂的查询,并使查询时间增加100毫秒。 有什么更好的办法告诉我EF,在对ParticipantCount
求和时, confData
的空列表应该只是零,而不是抛出异常? 令人讨厌的是,此错误仅在EF中发生; 如果我创建一个空的内存List<int>
并对其调用Sum()
,它将给我零,而不是引发异常!
使用Enumerable.DefaultIfEmpty
:
ParticipantCount = confData.DefaultIfEmpty().Sum(cd => cd.ParticipantCount)
您可以使用null合并运算符 ?? 如:
confData.Sum(cd => cd.ParticipantCount ?? 0)
我通过将Sum
行更改为:
ParticipantCount = (int?)confData.Sum(cd => cd.ParticipantCount)
令人困惑的是,即使IntelliSense告诉我正在使用Sum()
的int
重载,但在运行时它实际上是在使用int?
重载,因为confData
列表可能为空。 如果我明确告诉它返回类型是int?
它返回null
的空列表项,以后我可以空聚结null
秒至零。
无需尝试让EF生成返回0而不是null的SQL查询,而是在像这样处理客户端的查询结果时进行更改:
var results = from r in roomsData.AsEnumerable()
select new
{
r.Room,
r.ConferenceCount,
ParticipantCount = r.ParticipantCount ?? 0
};
AsEnumerable()
强制对SQL查询进行求值,随后的查询运算符是客户端LINQ-to-Objects。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.