Campo del set di dati DBNull - > int?
Domanda
campo int SQLServer. Valore a volte nullo. DataAdapter riempie il set di dati OK e può visualizzare i dati in DatagridView OK.
Quando si tenta di recuperare i dati in modo programmatico dal set di dati, il codice di recupero del campo del set di dati genera un errore StronglyTypedException.
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public int curr_reading {
get {
try {
return ((int)(this[this.tableHistory.curr_readingColumn]));
}
catch (global::System.InvalidCastException e) {
throw new global::System.Data.StrongTypingException("The value for column \'curr_reading\' in table \'History\' is DBNull.", e);
}
L'ho superato controllando DBNull nell'accessor get e restituendo null ma ... Quando la struttura del set di dati viene modificata (ancora in via di sviluppo) le mie modifiche (non sorprende) scompaiono.
Qual è il modo migliore per gestire questa situazione? Sembra che sia bloccato nel gestirlo a livello di set di dati. Esiste una sorta di attributo che può dire al generatore di codice automatico di lasciare le modifiche in atto?
Soluzione
Il set di dati avrà una proprietà booleana per indicare null.
int curr_reading = ( Iscurr_readingColumnNull) ?
<default_value> : row.curr_readingColumn;
Altri suggerimenti
Nella finestra di progettazione del set di dati digitato è presente la proprietà nullvalue
.
Per impostazione predefinita, il suo valore è genera eccezione
(da cui il codice generato)
Puoi impostarlo sul valore predefinito
desiderato. 0.
Quindi restituirà 0 anziché un'eccezione. (viene generato altro codice)
VS2008: funziona direttamente nel designer del set di dati.
VS2005: funziona solo per le stringhe nel designer ma è possibile modificare direttamente l'XSD e impostare la proprietà msprop: nullValue = " 0 "
-
Lascia solo il codice generato automaticamente. Non è possibile intercettare " " viene generato in modo da garantire che qualsiasi modifica apportata venga spazzata via prima o poi.
-
.NET (almeno i bit system.data di .NET 2.0) non converte da DBNull in nient'altro. Questo fa schifo ma non puoi farci nulla.
-
Scrivi un metodo di estensione chiamato ToNullable () o simile: può farlo:
.
public static Nullable<T> ToNullable(this object x){
if(x == DBNull.Value)
return default(T); // return null thing
else
return (T)x;
}
allora puoi farlo
int? thing = DataRow["column"].ToNullable<int>();
Se la memoria serve, è necessario contrassegnare la riga come modificata - usando .BeginEdit () o simile - quindi apportare le modifiche e salvare la riga, probabilmente usando .EndEdit () o simile. Potresti voler leggere un po 'di questi metodi (potrebbero essere su DataSet, DataTable o DataRow) - la mia memoria è un po' confusa.
Spero che questo aiuti almeno un po '.
if(row["curr_reading"] is DBNull){
}else{
row.curr_reading;
}