Usando Dapper para mapear más de 5 tipos

c# dapper sql

Pregunta

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.

Anteriormente modifiqué 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 tengo que hacerlo?

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

Respuesta aceptada

En un proyecto en el que trabajé, vi algo como esto para obtener más de 7 tipos mapeados. Usamos 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"
);

El queryString es autoexplicativo. 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, aquí puede leer sobre esto .


Respuesta popular

Puede usar una consulta dinámica y asignarla después. 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 conjunto de resultados bastante grande, otra opción podría ser usar múltiples consultas y luego usar un lector de cuadrículas. Eso podría funcionar para usted.

Ahí está el ejemplo tomado de la edad apta:

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


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué