Linq query with nullable sum

前端 未结 14 1880
粉色の甜心
粉色の甜心 2020-11-29 06:23
from i in Db.Items
select new VotedItem
{
    ItemId = i.ItemId,
    Points = (from v in Db.Votes
              where b.ItemId == v.ItemId
              select v.Poi         


        
相关标签:
14条回答
  • 2020-11-29 06:39

    Assuming Points is a List of Int32, how about something like:

    var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)
    
    0 讨论(0)
  • 2020-11-29 06:40

    Similar to previous answers, but you can also cast the result of the entire sum to the nullable type.

    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
    }
    

    Arguably this better fits what is really going on but it has the same effect as the cast in this answer.

    0 讨论(0)
  • 2020-11-29 06:43

    A simple but effective workaround would be to only sum the votes where Points.Count > 0, so you never have null values:

    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()
    }
    
    0 讨论(0)
  • 2020-11-29 06:44
    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() 
    }
    

    EDIT - ok what about this... (Shooting again since I don't know your model...):

    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) 
    }
    
    0 讨论(0)
  • 2020-11-29 06:44
            (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);
    

    This works, but isn't very pretty or readable.

    0 讨论(0)
  • 2020-11-29 06:47

    I had the same problem. Solved it with empty list union:

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

    In case of "Points" is integer this should work.

    0 讨论(0)
提交回复
热议问题