remarks example cref c# .net orm dapper

c# - example - Dapper tipos de retorno dinámico



remarks c# (3)

He estado usando dapper.net por ahora y es un muy buen mapeador ORM que funciona muy bien con los tipos dinámicos .Net pero noté que cuando Dapper recupera datos de la base de datos, regresa como tipo de fila Dapper. en cualquier otro tipo, como System.Dynamic.ExpandoObject?


¡Por supuesto!

Según la documentación de Dapper, utilice el método de consulta y obtenga su dinámica:

dynamic account = conn.Query<dynamic>(@" SELECT Name, Address, Country FROM Account WHERE Id = @Id", new { Id = Id }).FirstOrDefault(); Console.WriteLine(account.Name); Console.WriteLine(account.Address); Console.WriteLine(account.Country);

Como puede ver, obtiene un objeto dinámico y puede acceder a sus propiedades siempre que estén bien definidas en la declaración de consulta.

Si omite .FirstOrDefault() , obtiene un IEnumerable<dynamic> que puede hacer lo que quiera con él.


Tengo este problema y lo solucioné de esta manera!

La función Query() devuelve una colección de dinámicas que debajo son en realidad tipos de objetos Dapper.SqlMapper.DapperRow . El Dapper.SqlMapper.DapperRow es privado. Necesitaba agregar propiedades dinámicamente a los objetos Dapper.SqlMapper.DapperRow pero eso no parece funcionar. Como resultado, quería convertir el Dapper.SqlMapper.DapperRow en un ExpandoObject .

Pude construir este método genérico de ayuda como se muestra a continuación.

public class DapperHelpers { public static dynamic ToExpandoObject(object value) { IDictionary<string, object> dapperRowProperties = value as IDictionary<string, object>; IDictionary<string, object> expando = new ExpandoObject(); foreach (KeyValuePair<string, object> property in dapperRowProperties) expando.Add(property.Key, property.Value); return expando as ExpandoObject; } }

Entonces puedes usar eso así:

IEnumerable<ExpandoObject> result = db.SqlConn.Query(sqlScript) .Select(x=> (ExpandoObject)ToExpandoObject(x));

referencia: cuestiones dapper-punto-net 166


El objeto DapperRow está diseñado para compartir muchos estados entre filas. Por ejemplo, si obtiene 40 filas, los nombres de columna, etc., solo se almacenan una vez . Si utilizamos ExpandoObject , esto debería configurarse por fila. Por lo tanto, el uso de DapperRow como el detalle de implementación detrás de escena es una cuestión de eficiencia deliberada.

Tenga en cuenta que el objeto devuelto desde las API dynamic también se puede convertir como IDictionary<string,object> .

Sin embargo, estaría abierto a admitir otros tipos que admitan este uso del diccionario, de los cuales ExpandoObject es uno. Entonces sí, podría ser cambiado de tal manera que:

var rows = conn.Query<ExpandoObject>(...);

trabajos. Simplemente requiere código para soportarlo , y ese código no existe actualmente. Así que "no, pero tal vez en una futura compilación".

Tenga en cuenta también que no necesita usar DapperRow en absoluto ... El escenario más esperado es utilizar la API genérica para materializar sus propios tipos.