我正在尝试创建一个通用方法来使用 Dapper 获取多个数据集。我将指定预期数据类型的列表,该方法将为我提供特定数据类型的对象列表。
public async Task<List<object>> GetMultipleAsync<U>(string storedProcedure, U parameters, List<Type> types)
{
var result = new List<object>();
try
{
using (var multi = await _connection.QueryMultipleAsync(storedProcedure, parameters, commandType: CommandType.StoredProcedure, transaction: _transaction))
{
foreach (var type in types)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
{
// Handle list types
var elementType = type.GetGenericArguments()[0];
var method = typeof(SqlMapper.GridReader)
.GetMethods()
.FirstOrDefault(m => m.Name == nameof(SqlMapper.GridReader.ReadAsync) &&
m.IsGenericMethod);
var genericMethod = method.MakeGenericMethod(elementType);
var task = (Task)genericMethod.Invoke(multi, null);
await task.ConfigureAwait(false);
var resultProperty = task.GetType().GetProperty("Result");
var data = resultProperty.GetValue(task);
result.Add(data);
}
else
{
// Handle single value types
var method = typeof(SqlMapper.GridReader)
.GetMethods()
.FirstOrDefault(m => m.Name == nameof(SqlMapper.GridReader.ReadSingleAsync) &&
m.IsGenericMethod);
var genericMethod = method.MakeGenericMethod(type);
var task = (Task)genericMethod.Invoke(multi, null);
await task.ConfigureAwait(false);
var resultProperty = task.GetType().GetProperty("Result");
var data = resultProperty.GetValue(task);
result.Add(data);
}
}
}
}
catch (Exception ex)
{ // Handle exception;
}
return result;
}
我将发送预期类型的数据类型列表,例如
var types = new List<Type>
{
typeof(List<ModelA>),
typeof(List<ModelB>),
typeof(long)
};
var resultMultiple = await _dataAccess.GetMultipleAsync<DynamicParameters>(storedProcedure, parameters, types);
输出应该是
var ListA = resultMultiple[0] as List<ModelA>;
var ListB = resultMultiple[1] as List<ModelB>;
var val = resultMultiple[2] as long;
此方法会抛出错误
Parameter count mismatch.
你把这件事搞得太复杂了。 Dapper 已经允许您传递
Type
对象来动态构造它,您不需要自己执行此操作。您唯一的问题是构建 List<T>
,因为 Dapper 返回 IEnumerable<T>
。
public async Task<List<object>> GetMultipleAsync<U>(string storedProcedure, U parameters, List<Type> types)
{
var result = new List<object>();
try
{
using var multi = await _connection.QueryMultipleAsync(storedProcedure, parameters, commandType: CommandType.StoredProcedure, transaction: _transaction);
foreach (var type in types)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
{
// Handle list types
var elementType = type.GetGenericArguments()[0];
var data = multi.ReadAsync(elementType);
var list = typeof(Enumerable).GetMethod(nameof(Enumerable.ToList)).Invoke(data);
result.Add(list);
}
else
{
// Handle single value types
var data = multi.ReadFirstOrDefaultAsync(type);
result.Add(data);
}
}
}
catch (Exception ex)
{ // Handle exception;
}
return result;
}
我必须说,在字段中保存连接和事务有点代码味道,并且只能在某种正确处理的工作单元对象上完成。