【问题标题】:How to handle null values in linq?如何处理 linq 中的空值?
【发布时间】:2013-04-11 12:06:29
【问题描述】:
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) 来过滤掉空值?
  • 或者是“List of things or null”,你可以使用Select(l => l == null ? Iterable.Empty : l)
  • 如果可以,只需修改GetAttendanceListOf,如果没有找到给定的“roll-no”,则返回空列表。

标签: c# linq select null dynamic-list


【解决方案1】:
_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 object pattern 通常是救命稻草,而对于集合,空集合通常在语义上类似于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)

【讨论】:

  • 这个扩展方法方案对我不起作用,它需要 2 个参数。但谢谢你的想法。我以其他方式实现了它并解决了我的问题。
  • 不确定我是否理解正确,但第一个参数是this AttendanceBAL bal,所以你仍然把它称为有一个参数:bal..GetAttendanceListOf(q._RollNumber)。这就是扩展方法的全部意义
【解决方案2】:

你可以试试

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

【讨论】:

    【解决方案3】:

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

    我建议您使用方法来创建对象,这将使您的查询更易于阅读和调试。我建议您分多个步骤执行此操作,以确定什么是 null 以及它在哪里执行失败。

    错误可能来自GetAttendanceListOf(),当有方法返回IList或IEnumerable时,如果没有结果,你应该返回一个空列表,它会阻止你每次验证它是否为null。

    【讨论】:

      【解决方案4】:

      根据@Zdeslav Vojkovic 的建议,修改GetAttendanceListOf 以在为空时返回空列表或执行以下操作:

      _AttendedDays = (新的出勤率() .GetAttendanceListOf(q._RollNumber) ?? Enumerator.Empty()) .Where(date => date != null) .Select(date => new DateTime(date._Date.Year, date._Date.Month, date._Date.Day)) 。清楚的() .ToList(),

      (你也许可以在没有额外括号的情况下做到这一点)

      【讨论】:

        【解决方案5】:

        为了快速修复,修改这一行

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

        到这里

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

        【讨论】:

          猜你喜欢
          • 2011-01-11
          • 1970-01-01
          • 1970-01-01
          • 2015-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-10
          相关资源
          最近更新 更多