2012-04-18 7 views
10

Attualmente sto creando una query SELECT che unisce 12 tabelle. Sto usando Dapper per tutte le mie altre domande e funziona benissimo. Il problema è che i metodi generici hanno solo cinque parametri generici.Utilizzo di Dapper per mappare più di 5 tipi

Ho precedentemente modificato il codice per supportare fino a 6 per un'altra query, ma ora non credo davvero che dovrei hackerare altri 6 livelli di generici.

C'è un modo per passare dapper una matrice di tipi e restituisce i risultati come una matrice di oggetti, che posso lanciare manualmente se necessario?

Anche io potrei avvicinarmi al problema nel modo sbagliato! Qualsiasi aiuto sarà apprezzato!

risposta

19

In un progetto su cui ho lavorato ho visto qualcosa del genere per ottenere più di 7 tipi mappati. Abbiamo usato Dapper 1.38:

connection.Query<TypeOfYourResult> 
(
    queryString, 
    new[] 
    { 
     typeof(TypeOfArgument1), 
     typeof(TypeOfArgument2), 
     ..., 
     typeof(TypeOfArgumentN) 
    }, 
    objects => 
    { 
     TypeOfArgument1 arg1 = objects[0] as TypeOfArgument1; 
     TypeOfArgument2 arg2 = objects[1] as TypeOfArgument2; 
     ... 
     TypeOfArgumentN argN = objects[N] as TypeOfArgumentN; 

    // do your processing here, e.g. arg1.SomeField = arg2, etc. 
    // also initialize your result 

    var result = new TypeOfYourResult(...) 

    return result; 
    }, 
    parameters, 
    splitOn: "arg1_ID,arg2_ID, ... ,argN_ID" 
); 

La stringa di query è autoesplicativa. Il parametro splitOn dice come Dapper dovrebbe dividere le colonne dall'istruzione SELECT in modo che tutto possa essere mappato correttamente agli oggetti, you can read about it here.

+3

Contrassegnalo come la risposta dal momento che è la più aggiornata! Questo avrebbe funzionato perfettamente nel mio caso d'uso 3 anni fa! (come vola il tempo!) –

+0

fantastico avere questa risposta! – noobed

+0

Alleluia! : D Grazie Mister @Radek –

3

È possibile utilizzare una query dinamica e mapparla in seguito. Qualcosa di simile

var result = conn.Query<dynamic>(query).Select(x => new Tuple<Type1, Type2, Type3, Type4, Type5>( 
// type initialization here 
    new Type1(x.Property1,x.Property2), 
    new Type2(x.Property3,x.Property4), 
    new Type3(x.Property5,x.Property6) etc....)); 

Edit: Con un set di risultati piuttosto enorme, un'altra opzione potrebbe essere quella di utilizzare più querys e quindi utilizzare un lettore di griglia. Potrebbe funzionare per te.

C'è l'esempio preso dall'età Dapper:

var sql = 
@" 
select * from Customers where CustomerId = @id 
select * from Orders where CustomerId = @id 
select * from Returns where CustomerId = @id"; 

using (var multi = connection.QueryMultiple(sql, new {id=selectedId})) 
{ 
    var customer = multi.Read<Customer>().Single(); 
    var orders = multi.Read<Order>().ToList(); 
    var returns = multi.Read<Return>().ToList(); 
    ... 
} 
+0

L'ho preso in considerazione. Ma ho ~ 87 colonne da mappare. E la mia query si adatta perfettamente ai miei oggetti. La mia ultima risorsa è la mappa manuale, ma in caso contrario, mi piacerebbe molto non digitare tutte le colonne: P –

+1

Vedo, si potrebbe voler dare un'occhiata all'opzione Grid Reader - vedere la mia modifica :) – Alex

+0

Wouldn Voglio fare una moltitudine di domande quando si fa il trucco. Ma grazie per l'aiuto :) –

2

Questo è stato risposto molto tempo fa, ma vorrei aggiungere i miei due centesimi qui. Invece di modificare manualmente il codice sorgente di Dapper, perché non devi creare una classe poco con quei campi e usare la tua query come una tabella?

La mappatura funzionerebbe bene, so che è un problema anche fare quella definizione di classe, ma sembra più facile che affrontare gli aggiornamenti di Dapper successivi.

+0

Questo codice è completamente scomparso ora (e è diventato open source: https://bitbucket.org/cdroulers/invup). Ma potrei usarlo per un altro progetto più tardi. Grazie per la risposta! –