Как обрабатывать значения null в linq?

recordsList.ListOfRecords = new StudentRecordsBAL()
                                .GetStudentsList()
                                .Select(q => new StudentRecords()
            {
                _RollNumber = q._RollNumber,
                _Class = q._Class,
                _Name = q._Name,
                _Address = q._Address,
                _City = q._City,
                _State = q._State,
                _Subjects = q._Subject,
                _AttendedDays = new AttendanceBAL()
                                    .GetAttendanceListOf(q._RollNumber)
                                    .Where(date => date != null)
                                    .Select(date => 
                                        new DateTime(date._Date.Year, date._Date.Month, date._Date.Day))
                                    .Distinct()
                                    .ToList(),
                _AttendedSubjects = GetAttendedSubjects(q._RollNumber)                                            
        }).ToList(); 

метод GetAttendanceListOf(q._RollNumber) в приведенном выше коде будет возвращен список записей из базы данных или "null", если нет записей для пройденного"roll-no". Запрос linq будет прерван, генерируя ошибку

"значение не может быть null".

есть ли способ справиться с этой ошибкой и заставить LINQ перейти к следующему шагу?

5 ответов


_AttendedDays = new AttendanceBAL()
    .GetAttendanceListOf(q._RollNumber)
    .Where(date => date != null)
    .Select(date => new DateTime(date._Date.Year, date._Date.Month, date._Date.Day))
    .Distinct()
    .ToList(),

проблема с запуском Where() на нулевой экземпляр. Возможные решения:

1) изменить GetAttendanceListOf вернуть пустой список, если нет посещаемости (хорошая идея в целом, как null шаблон объекта очень часто является спасателем жизни, а для коллекции пустая коллекция часто семантически похожа на null)
2) Если вы не контролируете этот метод, напишите безопасный метод расширения, который вернет пустой список в случае null, например,

List<AttendanceType> SafeAttendanceList(this AttendanceBALType bal, RollNumber rn)
{
    return bal.GetAttendanceListOf(rn) ?? new List<AttendanceType>();
}

тогда назовите это как:

_AttendedDays = new AttendanceBAL()
    .SafeAttendanceListOf(q._RollNumber)
    .Where(date => date != null)

Вы можете попробовать

recordsList.ListOfRecords = new StudentRecordsBAL().GetStudentsList().Select(q => 
            {
                var attendanceList = new AttendanceBAL().GetAttendanceListOf(q._RollNumber);
                if (attendanceList == null)
                    return null;
                return new StudentRecords()
                    {
                        _RollNumber = q._RollNumber,
                        _Class = q._Class,
                        _Name = q._Name,
                        _Address = q._Address,
                        _City = q._City,
                        _State = q._State,
                        _Subjects = q._Subject,
                        _AttendedDays = attendanceList.Where(date => date != null).Select(date => new DateTime(date._Date.Year, date._Date.Month, date._Date.Day)).Distinct().ToList(),
                        _AttendedSubjects = GetAttendedSubjects(q._RollNumber)
                    };
            }).Where(q => q != null).ToList(); 

проверяет, что вы не делаете Where операция над нулевым объектом и отфильтровать любые нулевые результаты.


Linq ToList () вернет пустой список, если результатов нет. Ошибка может прийти откуда угодно.

Я бы рекомендовал вам использовать методы для создания ваших объектов, это облегчит чтение и отладку вашего запроса. Я бы рекомендовал вам сделать это в несколько шагов, чтобы определить, что получает null и где именно он не выполняется.

ошибка может исходить из GetAttendanceListOf (), при наличии методов, возвращающих IList или IEnumerable, вы должны возвращайте пустой список, если нет результатов, это помешает вам проверять каждый раз, если он равен null или нет.


как предложил @Zdeslav Vojkovic modify GetAttendanceListOf вернуть пустой список, если значение null или сделать что-то вроде:

_AttendedDays = (new AttendanceBAL()
    .GetAttendanceListOf(q._RollNumber) ?? Enumerator.Empty<typeofrecord>())
    .Where(date => date != null)
    .Select(date => new DateTime(date._Date.Year, date._Date.Month, date._Date.Day))
    .Distinct()
    .ToList(),

(возможно, вы сможете сделать это без дополнительных скобок)


для быстрого исправления измените эту строку

_AttendedDays = новый AttendanceBAL().GetAttendanceListOf (q._RollNumber).Где...

этой

_AttendedDays = (новый AttendanceBAL ().GetAttendanceListOf (q._RollNumber)??новый список()).Где...