当DateTime字段为空时,LINQ中的"指定的强制转换无效"

Azr*_*ria 1 c# datetime exception

我遇到了问题.我的代码使用LINQ.

var resultCases = from row2 in dtCases.AsEnumerable()
                  where row2.Field<int>("caseID") == caseID2
                  select new
                  {
                              caseName = row2["caseName"].ToString(),
                              caseCourtPlace = row2["caseCourtPlace"].ToString(),
                              caseCourtRef = row2["caseCourtRef"].ToString(),
                              caseOfficeRef = row2["caseOfficeRef"].ToString(),
                              effectiveDate = ((DateTime)row2["caseEffectiveDate"]),
                              closedDate = ((DateTime)row2["caseClosedDate"]),
                              caseFolderPath = row2["casesFolderPath"].ToString(),
                              category = row2["categoryName"].ToString(),
                              department = row2["departmentName"].ToString(),
                              empName = row2["empName"].ToString(),
                              judgeName = row2["judgeName"].ToString(),
                              asName = row2["asCasesName"].ToString(),
                  };
Run Code Online (Sandbox Code Playgroud)

如果closedDateeffectiveDate返回DBnull.Value,我明白了

InvalidCastException未处理 - 指定的强制转换无效.

那我怎么能防止这个错误呢?

小智 5

tldr; 这个问题有两个方面:数据表使用DBNull.Value表示"空"值既不DBNull.Value或者null是强制转换DateTime.

Field<T>后来加入的扩展方法进行处理的DBNull和可空/引用类型空值容易得多; 它还隐藏了强类型签名背后的转换.这些LINQ to DataSet扩展方法知道如何适当地映射DBNull.Valuenull.

由于这种使用row.Field<DateTime?>("caseEffectiveDate")将返回无论是DateTime?用一个值(如果该查询返回的值),或者null,它也可能会抛出一个异常,如果服务器返回一个不兼容的值-但它永远不会返回DBNull.Value.

然而,标准row["caseEffectiveDate"]将返回一个DateTime值(或一些其他类型的),或者DBValue.Null铸能DateTime?(更不用说DateTime中描述的错误)和结果.

以下是如何最小化重现此异常:

object v = DBNull.Value;
DateTime dt = (DateTime)v;
Run Code Online (Sandbox Code Playgroud)

但是,可以将a转换nullDateTime?:

object v = null;
DateTime? maybeDt = (DateTime?)v;
Run Code Online (Sandbox Code Playgroud)

然后琐碎地将它合并到DateTime需要的地方:

object v = null;
DateTime? dt = (DateTime?)v ?? DateTime.MinValue;
Run Code Online (Sandbox Code Playgroud)