nullable 합계가있는 LINQ 쿼리
-
22-08-2019 - |
문제
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.
합계가 int가 아닌 int를 반환하고 int를 제공하기 때문에 int를 제공하기 때문에 나는 그것을 가정합니다. 입력은 동일한 오류 만 제공하기 때문에 SUM이 INT에서만 작동 할 수 있습니다.
이것에 대한 좋은 해결 방법이 있습니까?
해결책
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)
}
다른 팁
귀중한 양의 합을 사용하려고하므로 가치를 무효가 될 수 있습니다.
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를 사용하여 Tolist () 메소드를 사용하여 객체를 사용해 볼 수도 있습니다.
LinqToObjects 빈 컬렉션의 합계는 0이며, 여기서 LinqToSql 빈 컬렉션의 합은 null입니다.
이것을 확인하십시오 :
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을 반환합니다
간단하지만 효과적인 해결 방법은 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()
}
믹스에 다른 방법을 추가하려면 :)
Where(q=> q.ItemId == b.ItemId && b.Points.HasValue).Sum(q=>q.Points.Value)
비슷한 시나리오가 있었지만 합산 할 때 추가 필드를 비교하지 않았습니다 ...
Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);
포인트가 int32의 목록이라고 가정하면 다음과 같은 것은 어떻습니까?
var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)
나는 같은 문제가 있었다. 빈 목록 연합으로 해결했습니다.
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);
이 도움이되기를 바랍니다.
(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
이전 답변과 유사하지만 전체 합계 결과를 무효 유형에 시전 할 수도 있습니다.
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
}
아마도 이것은 실제로 일어나고있는 일에 적합하지만 캐스트와 같은 효과가 있습니다. 이 답변.
다른 해결책을 버릴 것이라고 생각했습니다. 나는 비슷한 문제가 있었고 이것이 내가 그것을 해결하게 된 방법입니다.
Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)