简体   繁体   English

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

[英]How can I make Sum() return 0 instead of 'null'?

I'm trying to use LINQ-to-entities to query my DB, where I have 3 tables: Room , Conference , and Participant . 我正在尝试使用LINQ-to-entities查询我的数据库,其中有3个表: RoomConferenceParticipant Each room has many conferences, and each conference has many participants. 每个房间都有很多会议,每个会议都有很多参与者。 For each room, I'm trying to get a count of its conferences, and a sum of all of the participants for all of the room's conferences. 对于每个房间,我正在尝试统计其会议数量,以及该房间所有会议的所有参与者的总和。 Here's my query: 这是我的查询:

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)
        }
    );

When I try and turn this into a list, I get the error: 当我尝试将其转换为列表时,出现错误:

The cast to value type 'System.Int32' failed because the materialized value is null. 强制转换为值类型'System.Int32',因为实例化值为null。 Either the result type's generic parameter or the query must use a nullable type. 结果类型的通用参数或查询必须使用可为空的类型。

I can fix this by changing the Sum line to: 我可以通过将“ Sum行更改为:

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

But the trouble is that this seems to generate a more complex query and add 100ms onto the query time. 但麻烦的是,这似乎会生成更复杂的查询,并使查询时间增加100毫秒。 Is there a better way for me to tell EF that when it is summing ParticipantCount , an empty list for confData should just mean zero, rather than throwing an exception? 有什么更好的办法告诉我EF,在对ParticipantCount求和时, confData的空列表应该只是零,而不是抛出异常? The annoying thing is that this error only happens with EF; 令人讨厌的是,此错误仅在EF中发生; if I create an empty in-memory List<int> and call Sum() on that, it gives me zero, rather than throwing an exception! 如果我创建一个空的内存List<int>并对其调用Sum() ,它将给我零,而不是引发异常!

使用Enumerable.DefaultIfEmpty

 ParticipantCount = confData.DefaultIfEmpty().Sum(cd => cd.ParticipantCount)

You may use the null coalescing operator ?? 您可以使用null合并运算符 ?? as: 如:

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

I made it work by changing the Sum line to: 我通过将Sum行更改为:

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

Confusingly, it seems that even though IntelliSense tells me that the int overload for Sum() is getting used, at runtime it is actually using the int? 令人困惑的是,即使IntelliSense告诉我正在使用Sum()int重载,但在运行时它实际上是在使用int? overload because the confData list might be empty. 重载,因为confData列表可能为空。 If I explicitly tell it the return type is int? 如果我明确告诉它返回类型是int? it returns null for the empty list entries, and I can later null-coalesce the null s to zero. 它返回null的空列表项,以后我可以空聚结null秒至零。

Instead of trying to get EF to generate a SQL query that returns 0 instead of null, you change this as you process the query results on the client-side like this: 无需尝试让EF生成返回0而不是null的SQL查询,而是在像这样处理客户端的查询结果时进行更改:

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

The AsEnumerable() forces the SQL query to be evaluated and the subsequent query operators are client-side LINQ-to-Objects. AsEnumerable()强制对SQL查询进行求值,随后的查询运算符是客户端LINQ-to-Objects。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何为json属性而不是“ data”返回null:[] - How can i return null for a json property instead of “data”: [] 如何让我的视图返回集合的总和? - How can I make my view return the sum of a collection? 如何在LINQ Select Sum中设置零值而不是null - How can I set a zero-value instead of null in LINQ Select Sum 如何使函数返回IEnumerable <string> 而不是C#中的字符串 - How can I make a function return IEnumerable<string> instead of a string in C# 如果选择的值为null,如何使Linq选择返回值? - How can I make my Linq select return values if the value selected is null? Linq2SQL:总是让.Sum()返回0而不是null - Linq2SQL: Always get .Sum() to return 0 instead of null 如何从Asp.net MVC的ListBoxFor选择框中返回空列表而不是空列表? - How can I return an empty list instead of a null list from a ListBoxFor selection box in Asp.net MVC? 如果计数等于 0,我怎样才能让这个 Android044 = g.Count(i =&gt; i.Android044 == 1) 返回一个空值? - How can I make this Android044 = g.Count(i => i.Android044 == 1) return a null if the count is equal to 0? 如何让ModelBinder为参数返回null? - How do I make the ModelBinder return null for a parameter? 如何返回 int 数组的总和和平均值? - How can I return the sum and average of an int array?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM