使用EnumerableRowCollection和DateTime时操作异常无效

本文关键字:操作 异常 无效 DateTime EnumerableRowCollection 使用 | 更新日期: 2023-09-27 18:21:30

我最近发现for循环中的以下行给了我一个错误。错误来自步骤EndTime,最后一行代码如下所示:

EnumerableRowCollection<DERP_Dataset.tblActualValueFloatRow> RowFirstStep = DERP_DataServiceDataSet.tblActualValueFloat.Where(t => t.PointSliceID == StepPointSliceId && t.ActualValue == stepnumbers[stepIndex] && t.UTCDateTime >= startDate).OrderBy(o => o.UTCDateTime);
EnumerableRowCollection<DERP_Dataset.tblActualValueFloatRow> RowNextStep = DERP_DataServiceDataSet.tblActualValueFloat.Where(t => t.PointSliceID == StepPointSliceId && t.ActualValue > stepnumbers[stepIndex] && t.UTCDateTime >= startDate).OrderBy(o => o.UTCDateTime);
DateTime StepStartTime = (RowFirstStep.First().HasErrors) ? DateTime.MaxValue : RowFirstStep.First().UTCDateTime;
string rowNextStepUTCDateTimeString = RowNextStep.First().UTCDateTime.ToString();
    DateTime StepEndTime = (RowNextStep.First().HasErrors) ? DateTime.MaxValue : RowNextStep.First().UTCDateTime;

错误:

A first chance exception of type 'System.InvalidOperationException' occurred in System.Core.dll
Message: {"Sequence contains no elements"}
Source: System.Core
StackTrace: at System.Ling.Enumerable.First[TSource](IEnumerable'1 source) 

试图弄清楚这一点:

  • 在此处找到链接
  • 使用RowNextStep.First().isNull不是布尔值,所以不能在循环中使用
  • 尝试放入一个伪字符串变量,但得到了完全相同的错误和异常,所以在尝试调试时没有学到任何新东西
  • 我相信RowNextStep.First().HasErrors每次都会评估为false,包括当我遇到错误时。不确定100%

对此事的任何说明都将不胜感激。

编辑

用建议修改了代码,它产生了一个更有用的错误。

DateTime StepEndTime = (RowNextStep.FirstOrDefault().HasErrors) ? DateTime.MaxValue : RowNextStep.First().UTCDateTime;

错误绝对为空。正如我现在得到的:

A first chance exception of type 'System.NullReferenceException' 

除此之外,还有什么方法可以检查null吗!RowNextStep.First()。有吗?如果必须的话我会用它,但如果可能的话我喜欢避免否定。

使用EnumerableRowCollection和DateTime时操作异常无效

试图从一个空对象中获取一个项会给您带来问题。

当您在一个空列表上调用object.First()时,它将抛出一个异常。因此,除非您已经知道有项目或正在计划处理异常,否则永远不要调用.First()。因此,如果使用.First(),则需要执行这两件事中的一件(检查项或处理异常)。

当您调用object.FirstOrDefault()时,您总是会得到一个对象。该对象将是第一个项,或者如果没有项,则是类型的默认值(通常为null)。在调用.FirstOrDefault()时,您在代码中遇到的异常是由于您还试图访问返回对象(.HasErrors)的属性。这导致了null引用异常(不能从null对象访问属性)。

请注意,您还在条件和赋值中多次调用数据集上的扩展方法,这是非常昂贵的。

可能最有效的处理方法是使用.FirstOrDefault()将第一个(或null)项存储在变量中。然后可以在三元条件和赋值块中使用它。

例如:

var firstRowNextStep = RowNextStep.FirstOrDefault();
DateTime StepEndTime = (firstRowNextStep == null || firstRowNextStep.HasErrors)
    ? DateTime.MaxValue
    : firstRowNextStep.UTCDateTime;

也可以考虑为RowFirstStep执行此操作(尽管它现在不会给您带来任何问题)。

RowFirstStep.First()的实例更改为任一

(RowFirstStep.FirstOrDefault() == null || RowFirstStep.FirstOrDefault().HasErrors())

(!RowFirstStep.Any()  || RowFirstStep.First().HasErrors())

正如George所说,.First()在对空集合调用时将抛出异常。当给定一个空集合时,.FirstOrDefault()将返回null(在这种情况下)。

不要调用.First()或FirstOrFefault()超过1次。您只需要执行一次查询。

var firstRecord = RowFirstStep.FirstOrDefault();
DateTime StepStartTime = DateTime.MaxValue;
if(firstRecord!=null && !firstRecord.HasErrors())
   StepStartTime =firstRecord.UTCDateTime;