2012-04-18 17 views
10

Actualmente estoy creando una consulta SELECT que une 12 tablas. He estado utilizando Dapper para todas mis otras consultas y funciona muy bien. El problema es que los métodos genéricos solo tienen cinco parámetros genéricos.Uso de Dapper para asignar más de 5 tipos

He modificado previamente el código para admitir hasta 6 para otra consulta, pero ahora realmente no creo que deba piratear 6 niveles más de genéricos.

¿Hay alguna manera de pasar apresurado una variedad de tipos, y devuelve los resultados como una matriz de objetos, que puedo lanzar manualmente si es necesario?

¡También podría estar abordando el problema de la manera incorrecta! ¡Cualquier ayuda será apreciada!

Respuesta

19

En un proyecto en el que trabajé, vi algo como esto para obtener más de 7 tipos mapeados. Utilizamos 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 cadena de consulta se explica por sí. El parámetro splitOn dice cómo Dapper debe dividir las columnas de la instrucción SELECT para que todo se pueda asignar correctamente a los objetos, you can read about it here.

+3

Marcado como la respuesta ya que es el más actualizado. ¡Esto hubiera funcionado perfectamente en mi caso de uso hace 3 años! (¡Cómo pasa el tiempo!) –

+0

¡Es genial tener esta respuesta! – noobed

+0

¡Aleluya! : D Gracias Señor @Radek –

3

Puede utilizar una consulta dinámica y asignarla posteriormente. Algo como esto

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....)); 

Editar: Con un gran conjunto de resultados más bien, otra opción podría ser el uso de múltiples querys y luego usar un lector de cuadrícula. Eso podría funcionar para usted.

Ahí está el ejemplo tomado de la era pulcro:

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

Lo he considerado. Pero tengo ~ 87 columnas para mapear. Y mi consulta se correlaciona perfectamente con mis objetos. Mi último recurso es el mapa manual, pero, de lo contrario, me gustaría mucho no escribir todas las columnas: P –

+1

Veo, es posible que desee echar un vistazo a la opción Grid Reader - ver mi edición :) – Alex

+0

Wouldn No quiero ejecutar una multitud de consultas cuando uno hace el truco. Pero gracias por la ayuda :) –

2

Esto ha sido contestada hace mucho tiempo, pero me gustaría añadir mi granito de arena aquí. En lugar de modificar manualmente el código fuente de Dapper, ¿por qué no creas una clase poco con esos campos y usas tu consulta como una tabla?

La asignación funcionaría bien, sé que es una pena también hacer esa definición de clase, pero parece más fácil que tratar con las actualizaciones posteriores de Dapper.

+0

Este código ha desaparecido completamente ahora (y fue de código abierto: https://bitbucket.org/cdroulers/invup). Pero podría usar eso para otro proyecto más tarde. ¡Gracias por la respuesta! –

Cuestiones relacionadas