在 LINQ2SQL 中返回可为 null 的 DateTime

Returning a nullable DateTime in LINQ2SQL

以下 LINQ2SQL 查询抛出错误,指出它无法将 null 放入 DateTime 或更具体地说

The null value cannot be assigned to a member with type System.DateTime which is a non-nullable value type

这是代码,错误出现在 LINQ 行,即 d = (from... 行。

internal static DateTime? GetDateOfLastSkew(DateTime date, DateTime expiry)
{
    object d;
    using (SAFEX db = new SAFEX())
    {
        d = (from skew in db.Skew
             where skew.CalibrationDate.Date <= date.Date
                && skew.Expiry.Date == expiry.Date
             select skew.CalibrationDate).Max();
    }

    return d == DBNull.Value ? null : d as DateTime?;
}

但是 d 是一个 object,因此它可以毫无问题地向其分配 null,这意味着它必须发生在该 LINQ 查询中的某处。

我做错了什么?

将结果 select 转换为可为空:

d = (from skew in db.Skew
     where skew.CalibrationDate.Date <= date.Date
        && skew.Expiry.Date == expiry.Date
     select ((DateTime?)skew.CalibrationDate)).Max();

return d;

当调用不可空类型的集合(如 DateTime)时,Max() 将 return 该不可空类型的值,或者如果集合。

d 可能是一个对象,但您尝试分配给它的唯一东西是一个 DateTime,所以您唯一要得到的东西是一个 DateTimeDateTime?(您可以将其拆箱)。它永远不会被设置为DBNull.Value(在linq中用处不大,主要用于直接与数据库打交道的较低级别)。

如果你知道总会有至少一个匹配的行,那么忘记 d 并只获取 DateTime 并让它在 [=32 上转换为 DateTime? =]:

internal static DateTime? GetDateOfLastSkew(DateTime date, DateTime expiry)
{
  using (SAFEX db = new SAFEX())
  {
    return (from skew in db.Skew
         where skew.CalibrationDate.Date <= date.Date
            && skew.Expiry.Date == expiry.Date
         select skew.CalibrationDate).Max(); // Max returns a DateTime.
  }
}

如果您不知道总会有至少一个匹配项,则在选择中转换为 DateTime?,这样 Max() 现在可以处理可为 null 的类型并且可以 return null 适当时:

internal static DateTime? GetDateOfLastSkew(DateTime date, DateTime expiry)
{
  using (SAFEX db = new SAFEX())
  {
    return (from skew in db.Skew
         where skew.CalibrationDate.Date <= date.Date
            && skew.Expiry.Date == expiry.Date
         select (DateTime?)skew.CalibrationDate).Max(); // Max returns a DateTime or null on no matches.
  }
}