【问题标题】:Why am I getting an InvalidOperationException with this Linq to Sql method?为什么我使用此 Linq to Sql 方法得到 InvalidOperationException?
【发布时间】:2009-04-22 08:55:43
【问题描述】:

当执行以下 linq to sql 语句时:

    var stuff = from l in _db.SqlLinks
                select new
                           {
                               Link = l,
                               Rating = (from v in l.SqlLinkVotes
                                         where v.Tag == tagId
                                               && v.VoteDate >= since
                                         select v.Vote).Sum(),
                               NumberOfVotes = (from v in l.SqlLinkVotes
                                                where v.Tag == tagId
                                                      && v.VoteDate >= since
                                                select v.Vote).Count(),
                               NumberOfComments = (from v in l.SqlLinkVotes
                                                   where v.Tag == tagId
                                                         && v.VoteDate >= since
                                                         && v.Comment != ""
                                                   select v.Vote).Count()
                           };

我得到一个 System.InvalidOperationException(空值不能分配给 Int32)。

通过调试,我发现这来自动态对象的 Rating 属性。

当特定链接没有 SqlLinkVotes 时,Sum() 会产生一个空值,但 Rating 是一个 int,而 linq to sql 认为 Sum() 会产生一个 int,而不是一个可为空的 int。

我可以很容易地编写一个存储过程来解决这个问题,但我认为这对我来说是更好地了解 linq to sql 的好方法。

请帮忙!

【问题讨论】:

    标签: c# sql linq linq-to-sql


    【解决方案1】:

    有一个Connect thread about this 建议您将Sum() 的结果转换为可空类型(在您的情况下为int?)。我怀疑如果您希望评级不可为空,则可以使用 null-coalescing 运算符:

    Rating = ((int?) (from v in l.SqlLinkVotes
                      where v.Tag == tagId
                         && v.VoteDate >= 
                      select v.Vote).Sum()) ?? 0
    

    无论如何,值得一试。

    【讨论】:

    • 啊哈!你打败了我!我刚刚发布了同样的内容。
    • 这个答案有效 - 几周前被这个咬了,找到了这个修复。
    • 这可是个令人沮丧的小问题
    【解决方案2】:

    看起来像简单地将 Rating 字段转换为可为空的 int 已修复它。

    这对其他人来说是否合理?

    var stuff = from l in _db.SqlLinks
                            select new
                                       {
                                           Link = l,
                                           Rating = (int?)(from v in l.SqlLinkVotes
                                                     where v.Tag == tagId
                                                           && v.VoteDate >= since
                                                     select v.Vote).Sum(),
                                           NumberOfVotes = (from v in l.SqlLinkVotes
                                                            where v.Tag == tagId
                                                                  && v.VoteDate >= since
                                                            select v.Vote).Count(),
                                           NumberOfComments = (from v in l.SqlLinkVotes
                                                               where v.Tag == tagId
                                                                     && v.VoteDate >= since
                                                                     && v.Comment != ""
                                                               select v.Vote).Count()
                                       };
    

    【讨论】:

    • 是的。正如我的回答所暗示的,如果需要,您可以使用 null-coalescing 运算符返回到不可为空的表单,使用 0 作为默认值。 (无论如何,我希望会起作用......)
    • 确实如此,谢天谢地!我正在把这个动态对象变成一个定义的对象,就在方法的后面一点,所以我要替换那里的空值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 2011-02-24
    相关资源
    最近更新 更多