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

我得到了这个查询,但是如果没有发现有exception的投票则失败:

 The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type. 

我假设它是因为sum返回一个int而不是一个可为空的int,给出一个int? 作为input只给出相同的错误,可能导致总和只在整数工作。

任何好的解决方法呢?

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

你想要使用Sum的可空forms,所以试着把你的值转换成可以为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

假设“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空集合之和为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); 

我有同样的问题。 解决它与空列表联盟:

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

如果“点”是整数,这应该工作。

我认为这是相同的情况。 我解决了它。 这是我的解决scheme:

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

我希望这个帮助。

可能是把这个查询到try / catch..if“exception”,那么没有发现票

假设点是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); 

这工作,但不是很漂亮或可读。

我有一个类似的问题,想出了什么我试图从数据库中得到的解决scheme,做一个指望,然后只有当我有什么回报做一笔款项。 因为某种原因无法让演员工作,所以如果其他人有类似的问题发表这个post。

例如

 Votes = (from v in Db.Votes where b.ItemId = v.ItemId select v) 

然后检查是否有任何结果,以便返回空值。

 If (Votes.Count > 0) Then Points = Votes.Sum(Function(v) v.Points) End If 

类似于以前的答案,但是您也可以将整个和的结果转换为可为空的types。

 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 } 

可以说这更适合于真正发生的事情,但它与这个答案中的演员效果相同。

我以为我会在那里抛出另一个解决scheme。 我有一个类似的问题,这就是我最终解决的问题:

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