使用EnumerableRowCollection和DateTime时出现Invalidoperationexception

时间:2014-09-11 17:16:36

标签: c# linq visual-studio-2013 invalidoperationexception

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

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) 

尝试解决这个问题:

  • 找到了here
  • 的链接
  • 使用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()。是吗?如果必须,我会使用它,但如果可能的话,我想避免否定。

3 个答案:

答案 0 :(得分:2)

尝试从空对象中获取导致问题的项目。

当您在空列表上调用object.First()时,它将引发异常。因此,除非您已经知道有项目或计划处理异常,否则您永远不会致电.First()。因此,如果您使用.First(),则需要执行这两项操作之一(检查项目或处理异常)。

当您致电object.FirstOrDefault()时,您将始终获得一个物品。如果没有项目,此对象将是第一个项目,或者类型的默认值(通常为null)。调用.FirstOrDefault()时,您在代码中遇到的异常是由于您还试图访问返回对象的属性(.HasErrors)。这导致空引用异常(您无法从空对象访问属性)。

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

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

例如:

var firstRowNextStep = RowNextStep.FirstOrDefault();

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

考虑为RowFirstStep执行此操作(即使它现在没有给您带来任何问题)。

答案 1 :(得分:0)

RowFirstStep.First()的实例更改为

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

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

正如George所说,.First()在调用空集合时会抛出异常。给定空集合时,.FirstOrDefault()将返回null(在本例中)。

答案 2 :(得分:0)

不要多次调用.First()或FirstOrFefault()。你只需要执行一次查询。

var firstRecord = RowFirstStep.FirstOrDefault();
DateTime StepStartTime = DateTime.MaxValue;

if(firstRecord!=null && !firstRecord.HasErrors())
   StepStartTime =firstRecord.UTCDateTime;