我正在使用 Dapper 与 Oracle托管并尝试使用QueryMultiple
方法。我在Oracle包中有一个存储过程,它返回多个记录集。我想重用我的代码用于多个包方法,并且返回的数据来自不同的源表,因此列和实际数据会有所不同。
为了解决这个问题,我有一个类使用IEnumerable<string>
来存储FieldNames,使用IEnumerable<object[]>
来存储每行的数据。
只有一个记录集,我可以使用ExecuteReader
方法迭代结果并自己添加它们。但是,我想使用QueryMultiple
在一次通话中获取所有内容。现在我有两个记录集回来但其他记录集可能会被添加。
经过几次不同的尝试后,我能够获得以下代码。但是,似乎应该有更好的方法来实现这一目标。下面是另一个SO问题中的一段代码,似乎是我想要的,但我无法让它工作。有没有人对我如何在下面的代码中获取FieldNames和数据有任何建议,以及是否有更好的方法使用Dapper API。顺便爱上精致的小巧玲珑。谢谢你的任何建议。
// class to load results into
public class Results {
public IEnumerable<string> FieldNames { get; set; }
public DetailInfo Detail { get; set; }
public IEnumerable<object[]> Data { get; set; }
}
// code to get the results from the database field names and data varies
// method is private so that external callers cannot pass any just any string as methodName
private Results GetTableResults(string methodName) {
var queryparams = new OracleDynamicParameters();
queryparams.Add(name: "l_detail_cursor", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
queryparams.Add(name: "l_data_cursor", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
// ... other parameters go here, removed for example
Results results = new Results();
string sql = string.Format("{0}.GET_{1}_DETAILS", PackageName, methodName);
using (IDbConnection db = new OracleConnection(this.ConnectionString)) {
db.Open();
using (var multi = db.QueryMultiple(sql: sql, param: queryparams, commandType: CommandType.StoredProcedure)) {
// detail in first cursor, no problems here
results.Detail = multi.Read<DetailInfo>().Single();
// --------------------------------------------------
// this is the code I'm trying to see if there is a better way to handle
// --------------------------------------------------
// data in second cursor
var data = multi.Read().Select(dictionary =>
// cast to IDictionary
dictionary as IDictionary<string, object>
);
// pull from Keys
results.FieldNames = data.First().Select(d => d.Key);
// pull from values
results.Data = data.Select(d => d.Values.ToArray());
// --------------------------------------------------
}
}
return results;
}
我试图尝试使用类似下面的内容但只在运行时获取有关需要指定splitOn的异常。我尝试使用像ROWNUM这样的东西,甚至给记录集一个&#34; id&#34;但这似乎没有帮助。
var data = multi.Read<dynamic, dynamic, Tuple<dynamic, dynamic>>(
(a, b) => Tuple.Create((object)a, (object)b)).ToList();