2011-12-08 10 views
9

IsDataReader [i] vs DataReader.GetValue (i) vs DataReader.GetString (i)

dataReader[i] 

logicamente equivalente a

dataReader.GetValue(i) 

Sono le stesse? Sono diversi? C'è una situazione in cui uno sarebbe appropriato rispetto all'altro?

ci sono documented differently:

  • Ottiene la colonna situata in corrispondenza dell'indice specificato
  • ritorno il valore del campo specificato.

Ma quando li uso entrambi restituiscono il valore del campo. Cosa significa "ottenere la colonna"? Cosa significa "restituire il valore di un campo"?


Bonus Chatter:

Quando chiamo:

reader[i]; 
reader.GetValue(i); 
reader.GetString(i); 

ho un String ogni volta

risposta

15

In ultima analisi, dipende dalla particolare implementazione di System.Data.IDataReader si fa riferimento , ma supponiamo che intenda lo System.Data.SqlClient.SqlDataReader.

In questo caso, reader[i] e reader.GetValue(i) do esattamente la stessa cosa. Infatti, reader[i] chiama internamente reader.GetValue(i). (Puoi vedere questo smontando il codice usando uno strumento come ILSpy.). Entrambi questi membri restituiscono il valore nella colonna i-esima della riga corrente e restituiranno correttamente indipendentemente dal tipo di valore (il tipo restituito è object). La documentazione per entrambi questi membri è un po 'fuorviante e potrebbe essere formulata in un modo migliore. Puoi usare uno di questi membri dove preferisci, scegli quello che ritieni migliore.

Considerando che reader.GetString(i) è specificamente progettato per restituire il valore contenuto nella colonna i-esima della riga corrente come string. Se il valore in quella colonna non è un string, verrà generato un InvalidCastException. Utilizzare questo metodo quando si è certi che il valore sia string e string sia il tipo con cui si desidera lavorare. Ciò renderà il tuo codice più conciso poiché non dovrai eseguire un cast.

Nel tuo caso specifico, il valore nella i-esima colonna della riga corrente deve essere di tipo string, motivo per cui il valore restituito da tutti e tre i membri è identico.

Se scritto correttamente, altre implementazioni di System.Data.IDataReader devono comportarsi allo stesso modo.

+0

Ci sono casi orribili di bordo, dove 'GetValue' restituisce un' byte', ma 'GetInt32' non è in grado di trasmettere un byte ad un Int32 –

+0

È difficile da dire (specialmente perché il codice smontato è difficile da seguire) ma appare il valore nella colonna deve essere già del tipo desiderato altrimenti verrà generata l'InvalidCastException (che è anch'essa un po 'fuorviante). Modificherò la risposta. –

+0

Infatti, la documentazione di GetInt32 (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getint32.aspx) afferma che "Nessuna conversione viene eseguita, quindi i dati recuperati devono già un intero con segno a 32 bit. " Gli altri metodi GetXXX sono documentati in modo simile. –