2012-03-29 4 views
3

J'ai une classe avec le code suivantCast DateTime non valide?

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); 
      } 
     } 
    } 

Cependant DateTime? les transtypages échouent avec un 'Cast Invalid'. J'ai vérifié la base de données SQL et le champ stocke des dates valides Donc je ne peux pas comprendre pourquoi, comme j'extraire des informations via le DataReader dans mon application, les champs datetime provoquent une distribution non valide.

Aidez-nous s'il vous plaît.

+0

Quel type est contenu dans 'caseReader'? – ChrisF

+2

Un de vos champs DateTime contient probablement un DBNull - autant que je sache, vous ne pouvez pas directement convertir DBNull en un type Nullable. Il y a cependant des extensions pour ce cas. – Alex

+0

En plus des autres réponses concernant les valeurs nulles, vous dites que le champ stocke des dates valides, mais les stocke-t-il en utilisant un type de données approprié (par exemple 'datetime',' datetime2' ou 'date')? –

Répondre

6

Vous allez vouloir changer la ligne qui se lit comme suit:

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

à:

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

ainsi que toutes les lignes similaires.

Les valeurs DBNull ne peuvent pas être castées à partir de types nullables.

+0

essayé cela mais il dit que DBNull est un type mais il est utilisé comme une variable ?! – PJW

+0

Je suis désolé. Essayez DBNull.Value. Voir ma modification. – Khan

0

Essayez avec le code suivant partie

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

Pourquoi convertir la valeur en une chaîne juste pour effectuer une vérification nulle? –

+0

@Damien_The_Unbeliever, je l'ai changé. Mais là, j'ai vérifié non seulement les valeurs nulles, mais aussi vide. –

3

Vos champs DateTime détiennent probablement une valeur DBNull que vous ne pouvez pas convertir directement.

Cependant, j'utiliserais une méthode d'extension sur votre DataReader pour la commodité.

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

// Utilisation

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

+1 Grande solution réutilisable. – Khan

+1

Les crédits vont en fait à Mark, il a eu l'idée de les emballer dans des extensions http://stackoverflow.com/a/9464730/1028323 – Alex

+0

C'est parce qu'il est apparenté à Chuck Norris. – Khan

0

Essayez de convertir le temps Date comme

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

Si caseReader ["DOA"] est DBNull.Value donnera une exception. – Dummy01

0

Je traite souvent DBNull.Value ...

J'utiliser cette méthode qui renverra la valeur de l'objet ou la valeur par défaut du type de valeur donné si la valeur de l'objet est 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); 
    } 

Utilisation:

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

Vous devez utiliser

DateTime.TryParse Method

ce pas jeter exception, comme

var mydate =(DateTime)datetimeString 

ou var myd ate = DateTime.Parse (datetimeString)

fait !!!

Questions connexes