72
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 が nullable int ではなく int を返し、sum に int を与えるためだと思いますか? 入力でのみ同じエラーが発生するため、おそらく sum は int でのみ機能します。

これに対する良い回避策はありますか?

4

14 に答える 14

75

Sum の null 許容形式を使用したいので、値を 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

于 2010-02-09T21:50:27.533 に答える
22
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) 
}
于 2009-03-30T08:46:39.943 に答える
20

Assuming "v.Points" is a decimal just use the following:

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
}
于 2010-12-13T15:58:51.050 に答える
14

これをチェックしてみてください:

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 を返します

于 2012-04-19T10:25:39.783 に答える
11

nullabe decimal へのキャストが気に入らない場合は、ToList() メソッドで Linq To Objects を使用することもできます。

LinqToObjects 空のコレクションの合計は 0 で、LinqToSql 空のコレクションの合計は null です。

于 2010-10-15T22:22:30.207 に答える
5

シンプルだが効果的な回避策は、Points.Count > 0 の投票のみを合計することです。これにより、null 値が発生することはありません。

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()
}
于 2009-03-30T08:53:11.300 に答える
2

私も同じ問題を抱えていました。空のリストユニオンで解決しました:

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

「ポイント」が整数の場合、これは機能するはずです。

于 2012-04-04T14:46:00.903 に答える
2

これも同じケースだと思います。解決しました。これが私の解決策です:

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

これが助けになることを願っています。

于 2012-11-28T08:44:42.770 に答える
0

私も同様の問題を抱えていて、データベースから取得しようとしているものをすべて取得し、それらをカウントして、何かが返された場合にのみ合計を計算するという解決策を思いつきました。何らかの理由でキャストを機能させることができなかったので、他の誰かが同様の問題を抱えている場合はこれを投稿してください。

例えば

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
于 2012-04-04T16:00:40.453 に答える
0

前の回答と同様ですが、合計の結果全体を 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
}

おそらく、これは実際に起こっていることにより適していますが、この回答のキャストと同じ効果があります。

于 2012-05-15T10:36:29.427 に答える
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);

これは機能しますが、見栄えも読みやすさも良くありません。

于 2009-03-30T10:24:17.540 に答える