2012-01-05 21 views
5

Sto provando a riutilizzare lo stesso codice che ho sempre utilizzato, ma ora sta riscontrando un errore.L'oggetto Nullable deve avere un valore # 2

Sto scorrendo varie tabelle utente, e lì mi fare questo:

DateTime dcdt = (DateTime)u.DateCreated; 
DateTime lldt = (DateTime)u.LastLogon; 
userRow["DateCreated"] = dcdt.ToShortDateString(); 

all'interno del ciclo. Ottengo l'errore:

System.InvalidOperationException: Nullable object must have a value. 

i punti salienti di errore "lldt" linea, invece di "dcdt", che viene prima. Questo è strano in sé e per sé. Entrambi questi campi nel database "Consenti null" sono selezionati. Ed entrambi potrebbero essere nulli o nessuno dei due potrebbe essere nullo.

I due valori sono entrambi elencati come DateTime? tipi tramite intellisense.

Non capisco perché ASP.NET si rifiuta di consentire l'output vuoto per le date nulle. Se è vuoto/nullo, la logica suggerirebbe che ASP.NET non debba stampare nulla.

In quale altro modo si suppone di fornire date nulle? Ho provato ad aggiungere se le istruzioni per evitare di provare a lanciare DateTimes nulli, ma non aiuta, non ha senso.

risposta

12

Come hai detto, il tipo di dati di u.LastLogon è DateTime?. Ciò significa che può o non può avere un valore. Colando a DateTime, stai richiedendo di avere un valore. In questo caso, non è così.

A seconda di cosa si sta cercando di fare con esso, si consiglia di controllare la proprietà HasValue:

userRow["LastLogon"] = u.LastLogin.HasValue ? 
         (object) u.LastLogin.ToShortDateString() : DBNull.Value; 

Se la colonna del database LastLogon è di tipo DateTime, allora si dovrebbe essere in grado fare:

userRow["LastLogon"] = u.LastLogin.HasValue ? 
         (object) u.LastLogin.Value : DBNull.Value; 
+0

Quindi cosa faccio a riguardo? Non scrivo? Continuo a utilizzare ShortDateString() su DateTime? invece di DateTime? – Dexter

+0

Vedere il mio aggiornamento se il tipo di colonna è DateTime –

+1

Esattamente come 'u.LastLogon.Value.ToShortDateString()' non funziona? –

1

Il problema è .NET null non è la stessa di SQL NULL. SQL Null è System.DBNull. Quindi è un valore [non- null] in .NET.

+0

Quindi, come faccio a fare in modo che non debba stampare nulla o stampare una data se disponibile? – Dexter

+0

Tecnicamente Frazell è corretto, ma sono abbastanza sicuro che la traduzione avvenga automaticamente. Se la tua colonna datetime è nullo, vedrai un .net null. Ma non è questo il problema, devi scrivere del codice per verificare se è nullo e non stampare nulla. Come hai visto, il modo più compatto per farlo è con? ASP.NET non lo farà per te. –

1

Sembra che si sta tentando di chiamare un metodo (dcdt.ToShortDateString()) su un DateTime? che non ha un valore (è, infatti, null). Prova questo:

dcdt.HasValue ? dcdt.ToShortDateString() : String.Empty; 

EDIT (Basta rileggere la domanda): Inoltre, non cercare di convertire in DateTime. Mantieni il nullable.

EDIT # 2 (sulla base dei commenti):

Prova questa:

if (dcdt.HasValue) 
{ userRow["DateCreated"] = dcdt.ToShortDateString(); } 
else 
{ userRow = DbNull.Value } 
+0

u.LastLogon.HasValue? u.LastLogon.Value.ToShortDateString(): DBNull.Value; o u.LastLogon.HasValue? u.LastLogon.ToShortDateString(): DBNull.Value; si rifiuta di lavorare Non si compilerà in questo modo. LastLogon è un tipo di DateTime ?. – Dexter

+0

Questo perché DBNull.Value non è una stringa, l'espressione deve restituire un tipo di dati coerente. Io modifico in modo appropriato –

+0

Penso di averlo risolto. Ho usato questo: userRow ["LastLogon"] = u.LastLogon.HasValue? u.LastLogon.Value.ToShortDateString(): String.Empty; – Dexter

1

Hai bisogno di fare qualcosa di simile al seguente nel codice di accesso ai dati:

DataTable dt  = ExecuteSomeQuery() ; 
object  value = dt.Rows[0]["nullable_datetime_column"] ; 
DateTime? instance = value != null && value is DateTime ? (DateTime?)value : (DateTime?)null) ; 

Se il la colonna restituita è NULL, verrà restituita come System.DBNull, altrimenti verrà restituita come un'istanza di DateTime (o qualsiasi altro tipo di mapping appropriato è — int, string, ecc.).Di conseguenza, è necessario verificare il tipo di oggetto restituito dalla query prima di provare a lanciarlo.

+0

È già DateTime? genere. Ora voglio convertirlo in una stringa usando la funzione ShortDateTimeString nella classe DateTime. Non mi lascerà. – Dexter

+1

In questo caso, 'string s = instance.HasValue? instance.Value.ToString(): ""; 'dovrebbe fare il trucco. –

+0

Sì, è corretto. Ma qualcun altro ti ha picchiato sulla risposta nel formato corretto. – Dexter

1

Ho visto che Dexter ha chiesto come avrebbe dovuto farlo. Bene, vorrei creare un'estensione.

static class DateTimeExtensions 
{ 
    public static string ToString(this DateTime? dateTime, string format) 
    { 
     return dateTime.HasValue ? dateTime.Value.ToString(format) : String.Empty; 
    } 
} 

E allora si può fare:

DateTime? dt = null; 
DateTime? dt2 = DateTime.Now; 
Console.WriteLine(dt.ToString("dd-MM-yy")); 
Console.WriteLine(dt2.ToString("dd-MM-yy")); 

Nota che posso chiamare metodo di estensione su un tipo nullable se l'oggetto è nullo.

+0

questa è una bella soluzione –

Problemi correlati