0

I've trying to query some results to fill a list of objects. When I do it using a foreach, it works, but when I try using linq lambda expression, throws a null refference. Also I only don't use the foreach code because take so much time.

Some know what is wrong?

Foreach code:

var aux = _myRepository.GetAll();
var processGames = new List<ProcessGamePersonDTO>();

foreach (var item in aux)
{
    var processGame = new ProcessGamePersonDTO
    {
        IdProcessList = item.ProcessPersonList != null && item.ProcessPersonList.Any()
            ? item.ProcessPersonList.Select(x => x.Process.Id).ToList()
            : new List<int>(),
        IdGame = item.Game.Id,
        GameName = item.Game.Name,
    };

    processGames.Add(processGame);
}

linq lambda code:

var aux = _myRepository.GetAll();
var processGames = aux.Select(item => new ProcessGamePersonDTO
{
    IdProcessList = item.ProcessPersonList != null && item.ProcessPersonList.Any()
            ? item.ProcessPersonList.Select(x => x.Process.Id).ToList()
            : new List<int>(),
    IdGame = item.Game.Id,
    GameName = item.Game.Name,
}).ToList();

Also, if I replace the Item.ProcessPersonList != null && Item.ProcessPersonList.Any() ? item.ProcessPersonList.Select(x => x.Process.Id).ToList() : new List<int>(), by some generic int list, like a new List<int>(), it dows not throws any error.

Striter Alfa
  • 1,378
  • 1
  • 12
  • 28
  • 3
    Use the debugger and figure out what's null. – Dave Zych Sep 18 '15 at 14:55
  • The first and second are the same, both are missing *some* null checks (eg, `item.Game`) but if the first works the second should do too (given the same input) – Jamiec Sep 18 '15 at 14:57
  • Just currious. Replace the ?: with a function call and see what happens – rerun Sep 18 '15 at 15:02
  • @DaveZych the ArgumentNUllException throws in IDProcessList, and the parameter name that throws this error is not in any entity or object that this query uses. – Striter Alfa Sep 18 '15 at 15:04
  • @OndrejTucny It makes no sense work in foreach and throws an exception in linq, using the same null error treatment – Striter Alfa Sep 18 '15 at 15:06
  • 1
    In declaring the `List<...>` you name it `ProcessGamePersonDTO` where later you use `processGames`? It looks like a syntax error. – Willem Van Onsem Sep 18 '15 at 15:22
  • @CommuSoft Sry, i writed it wrong when i translated the variables into english. Now i fixed the var declaration – Striter Alfa Sep 18 '15 at 16:49
  • @rerun Thanks for the tip, but it still throwing the exception in linq code – Striter Alfa Sep 18 '15 at 16:49
  • @Jamiec Only when i assign IdProcessList in linq throws the error. item.Game can't be null and have no occurrences in the database that it returns null – Striter Alfa Sep 18 '15 at 16:51
  • I asked my boss to help me and we found the error. So, aux is an IQueryable, and it only will fill itself when I call a `.ToList()` and I was trying to execute a `item.ProcessPersonList.Select(x => x.Process.Id).ToList()` before aux was with the values – Striter Alfa Sep 18 '15 at 18:13

1 Answers1

0

This is the equivalent to your foreach, but it likely won't run any faster:

var aux = _myRepository.GetAll();
var processGames = aux.Select(item => new ProcessGamePersonDTO
{
    IdProcessList = item.ProcessPersonList != null && item.ProcessPersonList.Any()
            ? item.ProcessPersonList.Select(x => x.Process.Id).ToList()
            : new List<int>(),
    IdGame = item.Game.Id,
    GameName = item.Game.Name
}).ToList();

If this doesn't work, then it is because of the difference in the order that things being evaluated and something is changing the values in your source as it is executing. Is there processing going on while evaluating ProcessPersonList or item.Game that could change the values of either (or values of what _myRepository.GetAll returns)?

Robert McKee
  • 20,124
  • 1
  • 35
  • 53
  • Thanks for the down vote without explaination, but the above code does fix this incorrect use of ProcessGamePersonDTO. – Robert McKee Sep 18 '15 at 15:43
  • i think there is nothing in the code while this processing that could alter the values. The repository method only returns the database content, does not change it. – Striter Alfa Sep 18 '15 at 16:57
  • Is ProcessPersonList being lazily loaded? If it is not a virtual function, then isn't it always null in the foreach? – Robert McKee Sep 18 '15 at 17:36
  • I asked my boss to help me and we found the error. So, aux is an IQueryable, and it only will fill itself when I call a `.ToList()` and I was trying to execute a `item.ProcessPersonList.Select(x => x.Process.Id).ToList()` before aux was with the values – Striter Alfa Sep 18 '15 at 18:12
  • 1
    I'm glad you found your solution, but your explanation isn't quite right. Even with an IQueryable, that code wouldn't execute until it is being evaluated (and filled). I'm guessing you did something else to fix it as well. Like `var processGames = aux.Include(x=>x.ProcessPersonList).Include(x=>x.Game).Include(x=>x.ProcessPersonList.Select(y=>y.Process)).Select...` – Robert McKee Sep 18 '15 at 18:21
  • I modified my code like this: `var processosGames = aux.Where(_=>_.ProcessoCandidato.Any()).ToList().Select(_ => new ProcessoGamePessoaDTO [...]`. Calling a `.ToList()` before the main `.Select()`, the aux will be filled and able to execute the all code without error. Sorry if my explanation was not good, I have some difficults to write in english, but not to read – Striter Alfa Sep 18 '15 at 18:32
  • 1
    Ah yes, that would do the same thing as `.Include(x=>x.ProcessoCandidato)` because now you are including that in the IQueryable. Your provider will know that it needs that information and eagerly load it rather than lazily load it, which I suspect your data classes aren't designed to do, so it would leave it null. – Robert McKee Sep 18 '15 at 18:37