Подтвердить что ты не робот

Запрос Linq с нулевой суммой

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, а не nullable int, давая сумму int? поскольку входной сигнал дает только ту же ошибку, вероятно, причиной того, что сумма работает только на ints.

Какое-либо хорошее обходное решение для этого?

4b9b3361

Ответ 1

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

Ответ 2

Вы хотите использовать форму с нулевым значением суммы, поэтому попробуйте присвоить значение значение nullable:

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

Ответ 3

Предполагая, что "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

Если вам не нравится кастинг с нулевым десятичным значением, вы также можете попробовать использовать Linq To Objects с помощью метода ToList(),

LinqToObjects Сумма пустой коллекции равна 0, где LinqToSql Сумма пустого набора равна null.

Ответ 5

Попробуйте проверить это:

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

Ответ 6

Простым, но эффективным обходным путем было бы суммировать голоса, где 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()
}

Ответ 7

Просто добавьте еще один метод в микс:)

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

У меня была та же проблема. Разрешил его с пустым объединением списков:

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

В случае, когда "Точки" являются целыми, это должно работать.

Ответ 9

Я думаю, что это тот же случай. Я решил это. Это мое решение:

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

Я надеюсь, что эта помощь.

Ответ 10

Может быть, этот запрос задан в try/catch..if "exception", тогда не было найдено ни одного голоса

Ответ 11

Предполагаемые точки - это список Int32, как насчет чего-то вроде:

var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)

Ответ 12

        (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

У меня была аналогичная проблема, и я придумал решение о том, как я пытаюсь выбраться из базы данных, рассчитываю на тех, и только тогда, если бы у меня было что-то возвращенное, делайте сумму. Не удалось заставить бросок работать по какой-то причине, поэтому опубликовать это, если у кого-то были подобные проблемы.

например.

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

Ответ 14

Как и в предыдущих ответах, но вы также можете передать результат всей суммы в тип с нулевым значением.

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
}

Возможно, это лучше подходит для того, что действительно происходит, но оно имеет тот же эффект, что и приведение в этот ответ.

Ответ 15

Думаю, я бы выбрал еще одно решение. У меня была аналогичная проблема, и именно так я решил ее решить:

Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)