Почему запрос LINQ вызывает исключение, когда я пытаюсь получить счетчик типа - PullRequest
15 голосов
/ 08 сентября 2010
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 ...

Ответы [ 4 ]

10 голосов
/ 08 сентября 2010

Это похоже на обычное исключение нулевой ссылки в linq2objects, когда он пытается выполнить ваши предикаты или проекции.

Случаи, когда вы получили исключение null ref, о котором я могу думать, это если некоторые элементы коллекции somedata имеют значение null, если h.Year имеет значение null (какой это тип?)или если "p.somemoredate" равен нулю ..

4 голосов
/ 08 сентября 2010

Снова отложено выполнение ударов!

(Во-первых, я предполагаю, что это вызвано тем, что 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.

Разобравшись вот так, гораздо проще увидеть, где генерируется исключение и где искать проблемы.

2 голосов
/ 08 сентября 2010

Исключение выдается в операторе Count (), поскольку LINQ использует отложенное выполнение, и фактический запрос LINQ не будет выполняться до тех пор, пока не будет вызван .Count(), .ToList() и т. Д.

1 голос
/ 30 июля 2018

Я столкнулся с той же проблемой. Раздражает, что MS не предоставила встроенное обнаружение и обработку нуля для агрегатных функций. Другая проблема заключается в том, что я хотел убедиться, что получил нулевой или нулевой результат возврата для пустых / пустых результатов запроса, поскольку я работал над панелями мониторинга / отчетами. В конечном итоге все эти таблицы будут содержать данные, но на ранних этапах вы получите много нулевых результатов. Прочитав несколько сообщений на эту тему, я придумал следующее:

Получите поля, которые вы хотите вернуть или позже примените агрегатные функции в первую очередь. Тест на нулевой возврат. Возвращает 0, если обнаружен ноль.

Если вы действительно получаете возвращенные данные, вы можете безопасно использовать / применять функции 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);
    }
}
...