Запрос 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, давая sum a int? поскольку входные данные дают только ту же ошибку, вероятно, причина sum работает только на ints.
любой хороший обходной путь для этого?
15 ответов:
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 как насчет этого... (Снова стреляю, так как я не знаю вашу модель...):
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) }
вы хотите использовать nullable форму Sum, поэтому попробуйте привести свое значение к 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) }
Ваш вопрос обсуждается здесь более подробно:
предполагая, что "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 }
Если вам не нравится приведение к nullabe decimal, вы также можете попробовать использовать Linq to Objects с помощью метода ToList (),
LinqToObjects сумма пустой коллекции равна 0, где LinqToSql сумма пустой коллекции равна нулю.
попробуйте проверить это:
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
простой, но эффективный обходной путь будет заключаться только в суммировании голосов, Где очки.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() }
просто добавить еще один метод в микс:)
Where(q=> q.ItemId == b.ItemId && b.Points.HasValue).Sum(q=>q.Points.Value)
у меня был похожий сценарий, но я не сравнивала дополнительное поле при суммировании...
Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);
У меня была та же проблема. Решил его с пустым списком 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() }
в случае" точек " является целым числом это должно работать.
Я думаю, что это тот же самый случай. Я решил ее. Это мое решение:
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);
Я надеюсь, что это поможет.
предполагая, что точки-это список Int32, как насчет чего-то вроде:
var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 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);
это работает, но не очень красиво или читабельно.
у меня была аналогичная проблема, и я придумал решение получить все, что я пытался получить из базы данных, сделать подсчет на них, а затем, только если у меня было что-то возвращенное, сделать сумму. Не удалось заставить актеров работать по какой-то причине, поэтому разместите это, если у кого-то еще были подобные проблемы.
например
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
аналогично предыдущим ответам, но вы также можете привести результат всей суммы к типу nullable.
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 }
возможно, это лучше соответствует тому, что происходит на самом деле, но это имеет тот же эффект, что и бросок в ответ.