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 ...
LINQは遅延実行を使用し、実際のLINQクエリは.Count()
、.ToList()
などを呼び出すまで実行されないため、例外はCount()ステートメントでスローされます。
これは、述語または射影を実行しようとしている間、linq2objectsの通常のnull参照例外のように見えます。
「somedata」コレクションの一部の要素がnullの場合、「h.Year」がnullの場合(これはどのタイプですか?)、または「p。 somemoredate」はnullです。
延期された実行が再びストライキ!
(最初に、これはコレクションのどこかでp.somemoredateがnullであることが原因であると推測されます。)
あなたの例を考えると、クエリされているビットを単純化したので、私たちが本当に知る方法はありません。それを正面から見ると、「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.
このように分割すると、例外がスローされる場所と、問題を探す場所を簡単に確認できます。
私は同じ問題に遭遇しました。 MSが集約関数に組み込みのnull検出と処理を提供しなかったことは厄介です。もう1つの問題は、ダッシュボード/レポートで作業していたときに、null /空のクエリ結果に対して0または$ 0の戻り結果を確実に取得したかったことです。これらのテーブルにはすべて最終的にデータが含まれますが、早い段階で多くのnullが返されます。このテーマに関する複数の投稿を読んだ後、私はこれを思いついた:
返したいフィールドを取得するか、後で集計関数を最初に適用します。 nullリターンをテストします。 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);
}
}