2012-12-28 6 views
5

Ho una funzione che restituisce un oggetto che rappresenta un record nel mio database più colonne aggiuntive. Invece di creare una classe separata per questo oggetto mi chiedevo se c'è un altro modo, ad esempio:Tipo di dati di ritorno di una query linq

public object GetRecord(string key) 
{ 
    var item = select new {column1, column2}; 

    return item; 
} 

public void main() 
{ 
    var item = GetRecord(1); 

    // I want to be able to reference column1 on item. 
    var x = item.column1; 
} 

risposta

8

Sì, ci sono altri modi (alcuni in realtà), ma consiglio vivamente di non usarne nessuno. L'opzione migliore per gestire questo caso è creare un nuovo tipo personalizzato che trattiene i dati che hai. Sarà di gran lunga l'opzione più gestibile.

I tipi anonimi sono stati progettati specificamente per essere utilizzati nell'ambito di un singolo metodo. Stai combattendo il design della funzionalità per fare altrimenti, e quindi sarà difficile da fare, molto probabilmente perderai Intellisense, molto probabilmente le prestazioni ne risentiranno, e il povero fiacco che deve tornare e mantenere il codice sarà non ho idea di cosa sta succedendo o come regolare la query.

Il problema principale con la maggior parte delle soluzioni alternative è che si perde il controllo del tempo di compilazione. Se la query rimuove un parametro, aggiunge un parametro, cambia un tipo, ecc. Il codice che lo usa non ha modo di sapere. Quando scrivi il codice per usare una query non hai modo di sapere quali sono tutte le parti di dati, quali sono i loro tipi, quali sono i nomi delle variabili, ecc. Devi preoccuparti di errori di battitura nei nomi delle variabili che il compilatore può 't prendere, e avrete costantemente bisogno di guardare il funzionamento interno del metodo che genera la query. Si perde la capacità di trattarlo come una scatola nera o astrazione, che è significativo.

Se siete preoccupati per il tempo e gli sforzi necessari per creare questi tipi personalizzati, esistono un certo numero di strumenti automatici progettati per generare tali classi basate su tabelle di database o altre fonti.

+1

+1, non vedo alcun motivo per _non_ creare un tipo personalizzato. –

6

Se si tratta di .net 4.0 uso dynamic parola chiave.

+0

Sto usando dinamico, ma presumo il nome della colonna wi Non comparirò nell'intelligenza. ma funzionerà in fase di runtime. – Arcadian

+0

Se si utilizza un altro ambito per cui è stato creato il tipo dinamico, intellisense non funzionerà. –

+0

Per intellisense è necessario utilizzare il tipo concreto (che non può essere modificato nella clausola select). Fai riferimento alla risposta di Felipe per questo. – Tilak

2

completando solo le altre risposte, è possibile utilizzare anche Generics per farlo. qualcosa di simile:

public T GetRecord<T>(string key) 
    where T : IAnyInterfaceWithProperties, new 
{ 
    var item = select new T { PropertyOfInterface = value, Property2 = value2 }; 

    return item; 
} 
+1

Questo è pieno di errori di sintassi. Metti il ​​vincolo 'new' dopo il vincolo dell'interfaccia, rimuovi il cast in' T' e 'select'. – Adam

+0

Grazie per i suggerimenti @codesparkle. Stavo pensando in questo caso, abbiamo davvero bisogno di selezionare la parola chiave? –

3

Anche se è NET 4.0 è possibile utilizzare un Tuple<object,object> quindi fare riferimento per item.Item1. È possibile utilizzare la digitazione degli oggetti anziché semplicemente object.

public Tuple<Column1Type,Column2Type> GetRecord(string key) 
{ 
    var item = select new Tuple<Column1Type,Column2Type>(column1, column2); 

    return item; 
} 
1

Si potrebbe pensare di utilizzare una libreria POCO per questo - farà esattamente ciò che si desidera.

si può rotolare il proprio o utilizzare uno che è già disponibile:

http://code.google.com/p/dapper-dot-net/

il codice sarà quindi simile a questa:

var result = connection.Query("select col1, col2 from table1"); 

var x = result[0].col1; 

Drapper permette anche di avere un tipo forte es .:

var result = connection.Query<myType>("select col1, col2 from table1"); 

' Now result is a list of myType