Dapper QueryMultiple读取结果为IDictionary

时间:2015-04-23 19:13:38

标签: c# dapper

我正在使用 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();

0 个答案:

没有答案