【问题标题】:Invalid Cast DateTime?无效的投射日期时间?
【发布时间】:2012-04-13 02:17:13
【问题描述】:

我有一堂课,代码如下

 public cCase(string pCaseNo, string pMode)
    {
        if (pMode == "new")
        {
            this._caseNo = Validate_CaseNo(pCaseNo);
        }
        if (pMode == "existing")
        {
            try
            {
                int intValidatedCaseNo = Validate_CaseNo(pCaseNo);
                string sqlText = "SELECT * FROM tblCases WHERE CaseNo = @CaseNo;";
                string strConnection = cConnectionString.BuildConnectionString();
                SqlConnection linkToDB = new SqlConnection(strConnection);
                linkToDB.Open();
                SqlCommand sqlCom = new SqlCommand(sqlText, linkToDB);
                sqlCom.Parameters.Add("@CaseNo", SqlDbType.Int);
                sqlCom.Parameters["@CaseNo"].Value = intValidatedCaseNo;
                SqlDataReader caseReader = sqlCom.ExecuteReader();
                if (caseReader.HasRows)
                    while (caseReader.Read())
                    {
                        this._claimant = caseReader["Claimant"].ToString();
                        this._defendant = caseReader["Defendant"].ToString();
                        this._caseType = caseReader["CaseType"].ToString();
                        this._occupation = caseReader["Occupation"].ToString();
                        this._doa = (DateTime?)caseReader["DOA"];
                        this._dateClosed = (DateTime?)caseReader["DateClosed"];
                        this._dateSettled = (DateTime?)caseReader["DateSettled"];
                        this._dateInstructed = (DateTime?)caseReader["DateInstructed"];
                        this._status = caseReader["Status"].ToString();
                        this._instructionType = caseReader["InstructionType"].ToString();
                        this._feeEstimate = (decimal?)caseReader["FeeEstimate"];
                        this._amountClaimed = (decimal?)caseReader["AmountClaimed"];
                        this._amountSettled = (decimal?)caseReader["AmountSettled"];
                        this._caseManager = caseReader["CaseManager"].ToString();
                    }
                caseReader.Close();
                linkToDB.Close();
                linkToDB.Dispose();
            }
            catch (Exception eX)
            {
                throw new Exception("Error finding case" + Environment.NewLine + eX.Message);
            }
        }
    }

但是日期时间呢?转换失败并出现“无效转换”。 我检查了 SQL 数据库并且该字段正在存储有效日期 所以我不知道为什么,当我通过 DataReader 将信息提取到我的应用程序中时,日期时间字段会导致无效转换。

请帮忙。

【问题讨论】:

  • caseReader 持有什么类型?
  • 您的一个 DateTime 字段可能包含一个 DBNull - 据我所知,您不能直接从 DBNull 转换为 Nullable 类型。然而,这种情况有扩展。
  • 以及关于空值的其他答案 - 您说该字段正在存储有效日期,但它是否使用适当的数据类型存储它们(例如 datetimedatetime2date) ?
  • 似乎 dateTime 字段的数据类型之一是 VARCHAR(MAX) 或 NTEXT。请检查SQL表中的类型,你可能会得到一些线索。

标签: c# sql winforms


【解决方案1】:

您将要更改以下内容:

this._doa = (DateTime?)caseReader["DOA"];

到:

if (caseReader["DOA"] != DBNull.Value)
    this._doa.Value = (DateTime)caseReader["DOA"];

以及所有类似的行。

DBNull 值不能从 Nullable 类型转换。

【讨论】:

  • 试过了,但它说 DBNull 是一种类型,但它像变量一样使用?!
【解决方案2】:

您的 DateTime 字段可能包含您无法直接转换的 DBNull 值。

但是,为了方便起见,我会在您的 DataReader 上使用扩展方法。

public static class DataReaderExtensions
{
  public static DateTime? ReadNullableDateTime(this IDataReader reader, string column)
    {
        return reader.IsDBNull(column) ? (DateTime?)null : reader.GetDateTime(column);
    }
}

// 用法

 this._dateInstructed = CaseReader.ReadNullableDateTime("DateInstructed");

【讨论】:

  • 功劳实际上归马克所有,他有想法将它们包装在扩展中 stackoverflow.com/a/9464730/1028323
  • 那是因为他和 Chuck Norris 有关系。
  • 你是说乔恩·斯基特?因为据我所知,Chuck Norris 不能将 DBNull 转换为 DateTime?虽然乔恩显然可以。
  • 赞成。请注意,这与 if-then 解决方案不同,如果数据库字段为空,则不会将任何内容分配给变量,它将不理会它。所以,如果它已经有一个可以持续存在的价值。
【解决方案3】:

你应该使用

DateTime.TryParse Method

this 不会抛出异常,如

var mydate =(DateTime)datetimeString

或 var mydate =DateTime.Parse(datetimeString)

会!!!

【讨论】:

    【解决方案4】:

    尝试以下代码部分

    this._doa = (caseReader["DOA"] == DBNull.Value ? DBNull.Value : Convert.ToDateTime(caseReader["DOA"]); 
    

    【讨论】:

    • 为什么要将值转换为字符串只是为了执行空检查?
    • @Damien_The_Unbeliever,我改了。但是我不仅检查了空值,还检查了空值。
    【解决方案5】:

    尝试将日期时间转换为

    this._doa = Convert.ToDateTime(caseReader["DOA"]);
    

    【讨论】:

    • 如果 caseReader["DOA"] 是 DBNull.Value 将给出异常。
    【解决方案6】:

    我经常和DBNull.Value打交道...

    因此,如果对象的值为DBNull.Value,则我使用此方法将返回对象的值或给定值类型的默认值。

        public static object GetValueOrDefault(object value, Type type)
        {
            if (value != DBNull.Value)
                return value;
    
            if (type.IsValueType == false)
                return null;
    
            Array array = Array.CreateInstance(type, 1);
    
            return array.GetValue(0);
        }
    

    用法:

    GetValueOrDefault(dataRecord.GetValue(fieldIndex), dataRecord.GetFieldType(fieldIndex)
    

    【讨论】:

      猜你喜欢
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-24
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多