72
from i in Db.Items
select new VotedItem
{
    ItemId = i.ItemId,
    Points = (from v in Db.Votes
              where b.ItemId == v.ItemId
              select v.Points).Sum()
}

我收到了这个查询,但是如果没有发现异常投票,它将失败:

The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.

我假设它是因为 sum 返回一个 int 而不是一个可为空的 int,所以给 sum 一个 int?由于输入仅给出相同的错误,可能导致 sum 仅适用于整数。

有什么好的解决方法吗?

4

14 回答 14

75

您想使用 Sum 的可为空形式,因此请尝试将您的值转换为可为空的:

from i in Db.Items
select new VotedItem
{
    ItemId = i.ItemId,
    Points = (from v in Db.Votes
              where b.ItemId == v.ItemId
              select v.Points).Sum(r => (decimal?) r.Points)
}

您的问题在这里更详细地讨论:

http://weblogs.asp.net/zeeshanhirani/archive/2008/07/15/applying-aggregates-to-empty-collections-causes-exception-in-linq-to-sql.aspx

于 2010-02-09T21:50:27.533 回答
22
from i in Db.Items
select new VotedItem
{
    ItemId = i.ItemId,
    Points = (from v in Db.Votes
              where b.ItemId == v.ItemId
              select v.Points ?? 0).Sum() 
}

编辑 - 好吧,这个怎么样......(再次拍摄,因为我不知道你的模型......):

from i in Db.Items
select new VotedItem
{
    ItemId = i.ItemId,
    Points = (from v in Db.Votes
              where b.ItemId == v.ItemId)
              .Sum(v => v.Points) 
}
于 2009-03-30T08:46:39.943 回答
20

假设“v.Points”是小数,只需使用以下内容:

from i in Db.Items
select new VotedItem
{
    ItemId = i.ItemId,
    Points = (from v in Db.Votes
              where b.ItemId == v.ItemId
              select (decimal?) v.Points).Sum() ?? 0
}
于 2010-12-13T15:58:51.050 回答
14

尝试检查一下:

var count = db.Cart.Where(c => c.UserName == "Name").Sum(c => (int?)c.Count) ?? 0;

所以,问题的根源是这样的 SQL 查询:

SELECT SUM([Votes].[Value])
FROM [dbo].[Votes] AS [Votes]
WHERE 1 = [Votes].[UserId] 

返回 NULL

于 2012-04-19T10:25:39.783 回答
11

如果您不喜欢转换为 nullabe 十进制,您也可以尝试使用带有 ToList() 方法的 Linq To Objects,

LinqToObjects 空集合之和为 0,其中 LinqToSql 空集合之和为空。

于 2010-10-15T22:22:30.207 回答
5

一个简单但有效的解决方法是仅对 Points.Count > 0 的投票求和,因此您永远不会有空值:

from i in Db.Items
select new VotedItem
{    
  ItemId = i.ItemId,
  Points = (from v in Db.Votes
            where b.ItemId == v.ItemId &&
            v.Points.Count > 0
            select v.Points).Sum()
}
于 2009-03-30T08:53:11.300 回答
4

只是为了在组合中添加另一种方法:)

Where(q=> q.ItemId == b.ItemId && b.Points.HasValue).Sum(q=>q.Points.Value)

我有类似的情况,但在求和时我没有比较额外的字段......

Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);
于 2013-09-05T15:37:50.557 回答
3

假设 Points 是一个 Int32 列表,那么类似:

var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)
于 2014-10-21T21:22:11.293 回答
2

我有同样的问题。用空列表联合解决它:

List<int> emptyPoints = new List<int>() { 0 };

from i in Db.Items
select new VotedItem
{
 ItemId = i.ItemId,
 Points = (from v in Db.Votes
           where b.ItemId == v.ItemId
           select v.Points).Union(emptyPoints).Sum()
}

如果“点”是整数,这应该有效。

于 2012-04-04T14:46:00.903 回答
2

我认为这是同样的情况。我解决了。这是我的解决方案:

var x = (from a in this.db.Pohybs
                 let sum = (from p in a.Pohybs
                            where p.PohybTyp.Vydej == true
                            select p.PocetJednotek).Sum()
                 where a.IDDil == IDDil && a.PohybTyp.Vydej == false
                 && ( ((int?)sum??0) < a.PocetJednotek)
                 select a);

我希望这会有所帮助。

于 2012-11-28T08:44:42.770 回答
1

以为我会在那里抛出另一个解决方案。我有一个类似的问题,这就是我最终解决它的方式:

Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)
于 2013-11-01T19:07:33.663 回答
0
        (from i in Db.Items
         where (from v in Db.Votes
                where i.ItemId == v.ItemId
                select v.Points).Count() > 0
         select new VotedItem
         {
             ItemId = i.ItemId,
             Points = (from v in Db.Items
                       where i.ItemId == v.ItemId
                       select v.Points).Sum()
         }).Union(from i in Db.Items
                  where (from v in Db.Votes
                         where i.ItemId == v.ItemId
                         select v.Points).Count() == 0
                  select new VotedItem
                  {
                      ItemId = i.ItemId,
                      Points = 0
                  }).OrderBy(i => i.Points);

这有效,但不是很漂亮或可读。

于 2009-03-30T10:24:17.540 回答
0

我遇到了类似的问题,并提出了解决方案,即从数据库中获取任何我想从数据库中取出的内容,对这些内容进行计数,然后只有在我有任何返回的情况下才进行总和。由于某种原因无法让演员工作,所以如果其他人有类似的问题,请发布此内容。

例如

Votes = (from v in Db.Votes
          where b.ItemId = v.ItemId
          select v)

然后检查是否有任何结果,以免返回 null。

If (Votes.Count > 0) Then
    Points = Votes.Sum(Function(v) v.Points)
End If
于 2012-04-04T16:00:40.453 回答
0

与之前的答案类似,但您也可以将整个总和的结果转换为可为空的类型。

from i in Db.Items
select new VotedItem
{
    ItemId = i.ItemId,
    Points = (decimal?)((from v in Db.Votes
              where b.ItemId == v.ItemId
              select v.Points).Sum()) ?? 0
}

可以说这更符合实际情况,但它与此答案中的演员具有相同的效果。

于 2012-05-15T10:36:29.427 回答