如何在linq中处理空值?

8
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) 会从数据库返回一系列记录,如果传递的“roll-no”没有记录,则返回“null”。如果Linq查询终止,则会生成错误信息:“值不能为空”。是否有一种方法可以处理此错误并使LINQ跳到下一步?

也许你可以只使用 Where(q => q != null) 来过滤掉空值? - Lorenzo Dematté
如果是“事物列表或空”,您可以使用类似于Select(l => l == null ? Iterable.Empty : l)的东西。 - Lorenzo Dematté
如果可以的话,只需修改GetAttendanceListOf函数,以便在给定“roll-no”没有找到任何内容时返回空列表。 - pfyod
5个回答

10
_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)如果你无法控制该方法,请编写一个安全的扩展方法,以防空值而返回空列表,例如:
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)

这种扩展方法方案对我不起作用,它要求2个参数。但是感谢您提供的想法。我用另一种方式实现了它并解决了我的问题。 - Gautam G
1
不确定我是否理解正确,但第一个参数是this AttendanceBAL bal,所以您仍然像只有1个参数一样调用它:bal..GetAttendanceListOf(q._RollNumber)。这就是扩展方法的全部意义。 - Zdeslav Vojkovic

0

Linq ToList() 如果没有结果将返回一个空列表。错误可能来自其他地方。

我建议您使用方法来创建对象,这将使您的查询更易于阅读和调试。我建议您分多个步骤进行操作,以确定哪些内容为空并且在哪里无法执行。

错误可能来自 GetAttendanceListOf(),当使用返回 IList 或 IEnumerable 的方法时,如果没有结果应该返回一个空列表,这将避免每次验证它是否为 null。


0

你可以尝试一下

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操作,并过滤掉任何空结果。


0

根据@Zdeslav Vojkovic的建议,修改GetAttendanceListOf方法,如果为空则返回空列表或者执行以下操作:

_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(),

(您可能可以在不使用额外括号的情况下完成此操作)


0

对于一个快速的修复,修改这一行代码

_AttendedDays = new AttendanceBAL().GetAttendanceListOf(q._RollNumber).Where...

变更为

_AttendedDays = (new AttendanceBAL().GetAttendanceListOf(q._RollNumber)??new List()).Where...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接