2016-05-30 23 views
7

Ho la seguente query:Perché il dapper restituisce ogni colonna numerica come Int64?

SELECT 
    [Person].[Id] AS [Person_Id], 
    [Person].[Name] AS [Person_Name], 
    [Address].[Id] AS [Address_Id], 
    [Address].[Number] AS [Address_Number], 
    [Address].[Street] AS [Address_Street],   
FROM [Person] 
LEFT JOIN [Address] ON [Person].[addressId] = [Address].[Id] 

che viene utilizzato per interrogare un in-memory DB SQLite come:

var rows = _database.Query(query); 

Tuttavia quando cerco di leggere i valori come Int32 ottengo InvalidCastException.

foreach (IDictionary<string, object> row in rows) 
{ 
    var someId = (int)row["Person_Id"]; 
    var someNumber = (int)row["Address_Number"]; 
} 

Il motivo per cui sto utilizzando dapper in questo modo è che, come un progetto parallelo sto costruendo alcune caratteristiche in cima dapper per mappare i valori in una POCO (io sono a conoscenza dei progetti simili ad esempio rainbow, dapper.extensions eccetera).

Quindi, qualcosa sulla falsariga di:

var rowVal = row[fieldName]; 
propInfo.SetValue(obj, rowVal, null);  

Anche in questo caso, ignorare il costo delle prestazioni associato alla chiamata riflessione.

Nell'esempio sopra il tipo di proprietà di POCO è int32 ea causa di questo problema non è possibile assegnare il valore allo obj.

Qualsiasi aiuto o idea sono molto apprezzati.

+1

Che tipo di RDBMS stai utilizzando? Non è azzimato farlo. Tuttavia, alcuni RDBMS * lo fanno internamente * (che significa esporre gli interi come Int64). Voglio incolpare mysql, ma non riesco a ricordare quale sia quello che fa questo. Fondamentalmente, se usi 'Query ' * con build recenti *, dovrebbe aggirarlo automaticamente. Spero che funzioni anche quando si utilizza l'API 'dynamic'. Tuttavia, se si utilizza l'API unbox non elaborata (come se fossi), allora ** devi ** per annullare l'iscrizione al tipo di dati effettivi: si tratta di una limitazione intrinseca del funzionamento di unboxing in C#. –

+0

Ciao Marc, Grazie per il commento, sto usando 'SQLite' e una vecchia versione di' Dapper', passerò all'ultima e riporterò. – MaYaN

+0

nota: se continui a utilizzare l'API '' stringa ', mi aspetto che continui a non riuscire - a quel punto sei solo unboxing e unboxing deve essere fatto al tipo giusto (ish, ci sono eccezioni) –

risposta

5

Non è Dapper, è SQLite. Vedere Datatypes In SQLite Version 3 (supponendo che si sta usando v3):

La classe di memorizzazione INTERO, per esempio, comprende 6 diversi tipi di dati interi di diverse lunghezze. Questo fa la differenza sul disco. B ut non appena i valori INTEGER vengono letti dal disco e in memoria per l'elaborazione, vengono convertiti nel tipo di dati più generale (numero intero con 8 byte). E così per la maggior parte, "storage class" è indistinguibile da "datatype" e i due termini possono essere usati in modo intercambiabile.

+0

Sì, sto utilizzando un database 'SQLite' in memoria. Ma secondo l'estratto sopra visto che è già in memoria, dovrebbe essere letto come 'int32' (32bit intero con segno) no? – MaYaN

+0

L'estratto dice che il tipo di dati sarà 8 byte, cioè Int64. –

+0

Sì, corretto, ero stupido! – MaYaN