remarks example cref c# orm dapper

c# - example - Tipos apuestos y anónimos



remarks c# (3)

¿Es posible usar tipos anónimos con Dapper?

Puedo ver cómo se puede usar dinámica, es decir

connection.Query<dynamic>(blah, blah, blah)

es entonces posible hacer una

.Select(p=> new { A, B ,C })

o alguna variación de eso después?

Editar

Pensé que te mostraría cómo estoy usando Dapper en este momento. Tiendo a almacenar en caché (usando un InMemoryCache) los datos, así que solo hago una consulta grande al principio (que es súper rápida usando Dapper) y luego uso Linq para ordenar todo en mi Repositorio.

using System; using System.Collections.Generic; using System.Configuration; using System.Data.Common; using System.Linq; using Dapper; namespace SomeNamespace.Data { public class DapperDataContext : IDisposable { private readonly string _connectionString; private readonly DbProviderFactory _provider; private readonly string _providerName; public DapperDataContext() { const string connectionStringName = " DataContextConnectionString"; _connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; _providerName = ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName; _provider = DbProviderFactories.GetFactory(_providerName); } public IEnumerable<MyDataView> MyData1 { get; private set; } public IEnumerable<MyDataView> MyData2 { get; private set; } protected string SqlSelectMyTable1Query { get { return @"SELECT Id, A, B, C from table1Name"; } } protected string SqlSelectMyTable2Query { get { return @"SELECT Id, A, B, C from table2Name"; } } public void Dispose() { } public void Refresh() { using (var connection = _provider.CreateConnection()) { // blow up if null connection.ConnectionString = _connectionString; connection.Open(); var sql = String.Join(" ", new[] { SqlSelectMyTable1Query, SqlSelectMyTable2Query }); using (var multi = connection.QueryMultiple(sql)) { MyData1 = multi.Read<MyDataView>().ToList(); MyData2 = multi.Read<MyDataView>().ToList(); } } } public class MyDataView { public long Id { get; set; } public string A { get; set; } public string B { get; set; } public string C { get; set; } } } }

El InMemoryCache se ve así

namespace Libs.Web { public class InMemoryCache : ICacheService { #region ICacheService Members public T Get<T>(string cacheId, Func<T> getItemCallback) where T : class { var item = HttpRuntime.Cache.Get(cacheId) as T; if (item == null) { item = getItemCallback(); HttpContext.Current.Cache.Insert(cacheId, item); } return item; } public void Clear(string cacheId) { HttpContext.Current.Cache.Remove(cacheId); } #endregion } public interface ICacheService { T Get<T>(string cacheId, Func<T> getItemCallback) where T : class; void Clear(string cacheId); } }


¿Es posible usar tipos anónimos con Dapper?

Por supuesto, vea la anulación de consultas no genéricas, devuelve un IDictionary<string, object> dinámico IDictionary<string, object> este objeto es un expando que se puede convertir o acceder con notación de puntos.

P.ej:

var v = connection.Query("select 1 as a, 2 as b").First(); Console.Write("{0} {1}",v.a, v.b) // prints: 1 2

es entonces posible hacer un .Select

Claro, obtienes un IEnumerable<dynamic> ... puedes ejecutar lo que quieras con eso.


Aquí hay otra solución para usar tipos anónimos con dapper:

public static class DapperExtensions { public static IEnumerable<T> Query<T>(this IDbConnection connection, Func<T> typeBuilder, string sql) { return connection.Query<T>(sql); } }

y úsalo así:

var data = connection.Query(() => new { ContactId = default(int), Name = default(string), }, "SELECT ContactId, Name FROM Contact");


Solo una pequeña mejora de la gran solución de Guillaume86:

public static IEnumerable<T> Query<T>(this IDbConnection connection, Func<T> typeBuilder, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) { return SqlMapper.Query<T>(connection, sql, param, transaction, buffered, commandTimeout, commandType); }