GroupBy с идентификатором возможного нулевого объекта

#c# #linq

#c# #linq

Вопрос:

У меня есть List<Item>

У каждого элемента есть программа, у которой есть идентификатор.

Если элемент еще не связан с программой, его program будет иметь значение null.

Я хотел бы сгруппировать все элементы по идентификатору программы

Это то, что я пробовал:

 var listaAgrupada = client.ListarItens(null, null, null).GroupBy(x => x.Programa.Id).ToList();
  

Это работает, если у всех элементов есть программа. Но если программа имеет значение null, она выдает исключение System.NullReferenceException:

Сообщение = «Ссылка на объект не установлена на экземпляр объекта».

Я полагаю, это связано с тем фактом, что, поскольку Program имеет значение null, я не могу получить доступ к его идентификатору.

Мне нужны все элементы, даже если их программа равна нулю (и я бы хотел, чтобы они также были сгруппированы по нулевой программе), поэтому их исключение не является вариантом.

Я обдумал два возможных решения, но я не уверен, как выполнить какое-либо из них:

Можно было бы сделать что-то вроде этого GroupBy(x => x.Programa == null || x.Programa.Id) (что не работает)

Другим было бы добавить пустой объект program, где program имеет значение null, но я не знаю, как это сделать

Конечно, я также открыт для других решений

Заранее спасибо

Комментарии:

1. Когда вы создаете элемент списка, присвойте ему значение ‘null’, которое вы никогда не будете использовать как EMPTY для строки или -99999 для int

Ответ №1:

Предполагая, что вы можете сгруппировать все null программы вместе и Id они будут неотрицательными, как насчет чего-то подобного:

 GroupBy(x => x.Programa == null ? -1 : x.Programa.Id)
  

Ответ №2:

С новым C # 6.0 вы также можете использовать:

 .GroupBy(x => x.Programa?.Id)
  

где ?. является нулевым условным оператором. Эта возможность была недоступна, когда был задан вопрос.

Комментарии:

1. Я думаю, вы должны поместить это как GroupBy (x => x?.Programa? .Id) тогда это связано с тем, что в его случае свойство Programma имеет значение null, а не элемент 🙂

2. @Martijn Спасибо за это исправление. Я исправил свой ответ. Я решил не обрабатывать случай, когда x ( Item сам по себе) равен null (который все равно взорвется), а только случай, когда Programa равно null. Именно так я интерпретирую вопрос и аналогично духу ответа dcp.

3. Я потратил последнюю неделю, пытаясь решить эту проблему. У меня возникла проблема с левым соединением, и я подумал, что проблема была в том, когда я попытался установить возможное нулевое значение на select new … И все это время проблема заключалась в groupby . Спасибо!

Ответ №3:

Смешивая оба ответа, это также можно использовать:

 .GroupBy(x => x?.Programa?.Id ?? -1)
  

Использование «??» определяет значение по умолчанию в случае, если «x» или «x.Program» равны нулю.