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

具有可空和的Linq查询

  •  67
  • AndreasN  · 技术社区  · 17 年前
    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而不是一个可为null的int,给sum一个int?由于输入仅给出相同的错误,可能会导致sum only对INT起作用。

    有什么好的解决办法吗?

    15 回复  |  直到 13 年前
        1
  •  75
  •   Scott Stafford    16 年前

    要使用可为null的Sum形式,请尝试将值强制转换为可为null的值:

    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

        2
  •  22
  •   Rashack    17 年前
    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) 
    }
    
        3
  •  20
  •   Jeroen Bernsen    15 年前

    假设“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
    }
    
        4
  •  12
  •   Pavel Shkleinik    11 年前

    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] 
    

        5
  •  11
  •   Emir    15 年前

    如果您不喜欢强制转换为nullabe decimal,您也可以尝试使用Linq to Objects和ToList()方法,

        6
  •  5
  •   Razzie    17 年前

    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()
    }
    
        7
  •  4
  •   nhahtdh Pankaj Wadhwa    12 年前

    只需在混合中添加另一种方法:)

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

    我有一个类似的场景,但在求和时我没有比较其他字段。。。

    Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);
    
        8
  •  3
  •   ProfNimrod    11 年前

    var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)
    
        9
  •  2
  •   Alex    14 年前

    我也有同样的问题。使用空列表联合解决了此问题:

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

    如果“Points”为整数,则应能正常工作。

        10
  •  2
  •   Alberto De Caro ChaosPandion    13 年前

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

        11
  •  1
  •   Jeff    12 年前

    Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)
    
        12
  •  0
  •   AndreasN    17 年前
            (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);
    

    这是可行的,但不是很好看或可读。

        13
  •  0
  •   tcmorris    14 年前

    我有一个类似的问题,我想出了一个解决方案,从数据库中取出我想得到的任何东西,对它们进行计数,然后只有在返回任何东西时才进行求和。由于某些原因,无法让演员组正常工作,因此如果其他人有类似问题,请发布此消息。

    例如

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

    If (Votes.Count > 0) Then
        Points = Votes.Sum(Function(v) v.Points)
    End If
    
        14
  •  0
  •   Community Mohan Dere    9 年前

    与前面的答案类似,但也可以将整个总和的结果强制转换为可为null的类型。

    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
    }
    

    可以说,这更符合实际情况,但它的效果与演员阵容相同 this answer .