2010-06-29 11 views
6

Viene visualizzato un errore quando si seleziona da una riga.AsEnumerable(). Sto usando il seguente codice ...Linq e DBNull - Errore

var rows = ds.Tables[0].AsEnumerable(); 
       trafficData = rows.Select(row => new tdDataDC 
       { 
        CalculationCount = row.Field<Int64>("biCalculationCountSeqID") 
        , Zone = row.Field<Int16>("siFkZoneId") 
        , Miles = row.Field<decimal>("dcMiles") 
        , Plaza = row.Field<Int16>("siFkPlazaId") 
        , VehicleCount = row.Field<int>("iVehicleCount") 


       }); 

maggior parte delle volte funziona bene, ma quando ci sono NULLS nel database che sto ricevendo questo errore "non può lanciare DBNull.Value digitare 'System.Int16 'Si prega di utilizzare un tipo nullable .. " Come posso correggere questo? Non voglio che i miei datacontracts abbiano tipi Nullable, mi piacerebbe usare un ternario o qualcosa del genere, e se un valore è NULL, usa solo 0. È possibile?

Grazie per qualsiasi aiuto,
~ ck

risposta

7

Ecco come si prova per i null ...

Plaza = row.IsNull("siFkPlazaId") ? 0 : row.Field<int>("siFkPlazaId") 
11

Si può sempre aggiungere un altro metodo di estensione (non testata):

public static T FieldOrDefault<T>(this DataRow row, string columnName) 
    { 
     return row.IsNull(columnName) ? default(T) : row.Field<T>(columnName); 
    } 

Quindi il tuo callsite ha il seguente aspetto:

var rows = ds.Tables[0].AsEnumerable(); 
       trafficData = rows.Select(row => new tdDataDC 
       { 
        CalculationCount = row.FieldOrDefault<Int64>("biCalculationCountSeqID") 
        , Zone = row.FieldOrDefault<Int16>("siFkZoneId") 
        , Miles = row.FieldOrDefault<decimal>("dcMiles") 
        , Plaza = row.FieldOrDefault<Int16>("siFkPlazaId") 
        , VehicleCount = row.FieldOrDefault<int>("iVehicleCount") 


       }); 
+1

mi piace la risposta di Marc, ma solo per ottenere un altro modo di farlo, è possibile cambiare i tipi di valore per essere annullabile (a breve? lungo? ecc.) e poi si fondono, quindi qualcosa come row.Field ("foo") ?? 0 –

+0

BTW, invece di fare 2 chiamate di riga, se T è sempre un tipo di valore, si potrebbe fare row.Field > (columnName) ?? default (T) anche se dubito che ne valga la pena se usi anche dei tipi di riferimento :) –

4

Se la tua proprietà è nullable puoi farlo anche tu;

Plaza = row.Field<int16?>("siFkPlazaId") 
+0

risposta stupenda! – DasDas

1

Sono abbastanza appassionato dell'operatore ??:

CalculationCount = row.Field<Int64?>("biCalculationCountSeqID") ?? 0 
       , Zone = row.Field<Int16?>("siFkZoneId") ?? 0 
       , Miles = row.Field<decimal?>("dcMiles") ?? 0.0m 
       , Plaza = row.Field<Int16?>("siFkPlazaId") ?? 0 
       , VehicleCount = row.Field<int>("iVehicleCount") 0;