I have created a small number of generic procedures using Dapper to return lists or individual items of any given type (using SPs on the SQL side) for use in a DI model data service, e.g.
public async Task<List<TOut>> GetList<TOut>(string proc, dynamic parameters)
{
await using var conn = new SqlConnection(connectionString);
var cmd = parameters == null ? new CommandDefinition(commandText: proc, commandType: CommandType.StoredProcedure) : new CommandDefinition(commandText: proc, commandType: CommandType.StoredProcedure, parameters: parameters);
return conn.Query<TOut>(cmd).ToList();
}
However I have been trying to extend this to use the QueryMultiple method to return an arbitrary number of result sets in one query (for efficiency, since the first query is quite expensive and the other result sets depend on it). I would like to end up with strongly typed result sets (not anonymous objects) without writing reams of code. However I can't see any way to come up with an arbitrary number of type parameters - so far the best I've managed to do is to produce one method for two result sets, one for three and so on:
public async Task<dynamic> Get2Lists<T1, T2>(string proc, dynamic parameters)
{
await using var conn = new SqlConnection(connectionString);
var cmd = parameters == null ? new CommandDefinition(commandText: proc, commandType: CommandType.StoredProcedure) : new CommandDefinition(commandText: proc, commandType: CommandType.StoredProcedure, parameters: parameters);
var result = conn.QueryMultiple(cmd);
return new
{
Table1 = result.Read<T1>(),
Table2 = result.Read<T2>()
};
}
public async Task<dynamic> Get3Lists<T1, T2, T3>(string proc, dynamic parameters)
{
await using var conn = new SqlConnection(connectionString);
var cmd = parameters == null ? new CommandDefinition(commandText: proc, commandType: CommandType.StoredProcedure) : new CommandDefinition(commandText: proc, commandType: CommandType.StoredProcedure, parameters: parameters);
var result = conn.QueryMultiple(cmd);
return new
{
Table1 = result.Read<T1>(),
Table2 = result.Read<T2>(),
Table3 = result.Read<T3>()
};
}
It seems to me there has to be a more elegant way - any suggestions?