public readonly IEnumerable<string> PeriodToSelect = new string[] { "MONTH" };
var dataCollection = from p in somedata
from h in p.somemoredate
where h.Year > (DateTime.Now.Year - 2)
where PeriodToSelect.Contains(h.TimePeriod)
select new
{
p.Currency,
h.Year.Month, h.Value
};
有人可以告诉我为什么在下面的代码行中会抛出异常吗?
int count = dataCollection.Count();
这是一个例外:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Linq.Enumerable.<SelectManyIterator>d__31`3.MoveNext()
at System.Linq.Enumerable.<SelectManyIterator>d__31`3.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at ...
答案 0 :(得分:10)
当它尝试执行谓词或预测时,它看起来像linq2objects中的普通空引用异常。
如果“somedata”集合的某些元素为null,如果“h.Year”为null(这是什么类型?),或者如果“p.somemoredate”为null ..
答案 1 :(得分:4)
延迟执行再次发生!
(首先,我的第一个猜测是,这是由于p.somemoredate在您的集合中某处为空而引起的。)
鉴于你的例子,我们无法真正知道,因为你已经简化了被查询的位。从表面上看,我会说无论“somedata”还是“somemoredate”都是你需要关注的东西。
为了解决这个问题,(当我真的绝望时)我将查询分成几部分并观察异常被抛出的地方。注意.ToArray()调用基本上会“停止”延迟执行暂时发生:
var sd = somedata.ToArray();
var x = (from p in sd from h in p.somemoredate.ToArray()).ToArray(); //My guess is that you'll get your exception here.
像这样分解,可以更容易地看到异常被抛出的位置,以及在哪里寻找问题。
答案 2 :(得分:2)
在Count()语句中抛出异常,因为LINQ使用延迟执行,并且在调用.Count()
,.ToList()
等之前不会执行实际的LINQ查询。
答案 3 :(得分:1)
我遇到了同样的问题。令人讨厌的是,MS没有为聚合函数提供内置的空检测和处理。另一个问题是,我要确保在处理仪表板/报表时,对于空值/空查询结果返回的结果为0或$ 0。所有这些表最终都会有数据,但是在早期,您会得到很多空值返回。在阅读有关该主题的多个帖子后,我想到了这一点:
检索要返回的字段,或者稍后将聚合函数应用于该字段。 测试是否为空。如果检测到null,则返回0。
如果确实返回了实际数据,则可以安全地使用/应用Count或Sum汇总Linq函数。
public ActionResult YourTestMethod()
{
var linqResults = (from e in db.YourTable
select e.FieldYouWantToCount);
if (linqResults != null)
{
return Json(linqResults.ToList().Count(), JsonRequestBehavior.AllowGet);
}
else
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}
下面的求和示例
public ActionResult YourTestMethod()
{
var linqResults = (from e in db.YourTable
select e.Total);
if (linqResults != null)
{
return Json(linqResults.ToList().Sum(), JsonRequestBehavior.AllowGet);
}
else
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}