Dapperで匿名型を使用することは可能ですか?
動的、つまり.
connection.Query<dynamic>(blah, blah, blah)
その後、それを行うことは可能ですか
.Select(p=> new { A, B ,C })
またはその後のそのバリエーション?
編集
今、私がDapperをどのように使用しているかをお見せしたいと思いました。 (InMemoryCacheを使用して)データをキャッシュする傾向があるので、最初に大きなクエリを1つだけ実行し(Dapperを使用すると非常に高速です)、Linqを使用してすべてをリポジトリで並べ替えます。
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; }
}
}
}
InMemoryCacheは次のようになります
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);
}
}
Dapperで匿名型を使用する別のソリューションを次に示します。
public static class DapperExtensions
{
public static IEnumerable<T> Query<T>(this IDbConnection connection, Func<T> typeBuilder, string sql)
{
return connection.Query<T>(sql);
}
}
次のように使用します。
var data = connection.Query(() => new
{
ContactId = default(int),
Name = default(string),
}, "SELECT ContactId, Name FROM Contact");
Dapperで匿名型を使用することは可能ですか?
確かに、非ジェネリッククエリのオーバーライドを確認してください。動的なIDictionary<string, object>
を返します。このオブジェクトは、ドット表記でキャストまたはアクセスできるエキスパンドです。
例えば:
var v = connection.Query("select 1 as a, 2 as b").First();
Console.Write("{0} {1}",v.a, v.b) // prints: 1 2
その後、
.Select
を行うことは可能ですか
確かに、IEnumerable<dynamic>
...を取得します。その上で何でも実行できます。
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);
}