ExpandoObject的多个数据集

时间:2016-08-19 13:21:37

标签: c#

我目前正在呼叫sproc。来自sproc的返回数据我返回了IDictionary<string, object> ExpandoObject。对于每sproc个数据集,这非常适用。现在我遇到了sproc,它在两个不同的表中返回数据。当我调用我的函数时,我只从第一个表中获取数据。所以我的问题是如何返回下一个数据集的数据。

注意 - 我无权更改细分

我到目前为止的代码是:

using(SqlDataReader reader = cmd.ExecuteReader())
{
   var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();

    foreach (IDataRecord record in reader as IEnumerable)
    {
       IDictionary<string, object> expando = new ExpandoObject() as IDictionary<string, object>;
       foreach (var name in names)
         expando[name] = record[name];

       yield return expando; //yield return to keep the reader open
    }
}

1 个答案:

答案 0 :(得分:3)

乍一看,它看起来并不重要。使用ReadNextResult方法将foreach替换为两个嵌套循环,并将方法返回类型从IEnumerable<dynamic>更改为IEnumerable<IEnumerable<dynamic>>(或IDictionary<string, object> dynamic)。

然而,问题是IEnumerable被懒惰地评估,并且DataReader是仅前向游标并且只能被消耗一次。

一种解决方案可能是将每个结果(数据集)缓冲到内存中(例如使用List<dynamic>),然后再将其返回给调用者,但这会破坏延迟执行的好处。

我会建议你采用另一种方法 - 一种返回以下类型的平面结果集的方法,而不是进行缓冲:

public struct QueryResult
{
    public readonly int Index;
    public readonly dynamic Data;
    internal QueryResult(int index, dynamic data)
    {
        Index = index;
        Data = data;
    }
}

其中Index字段将包含结果(数据集)索引(0,1,2等)。这将保留延迟执行的好处,并让调用者使用最合适的方式处理它 - 例如使用foreach循环,LINQ GroupByMoreLINQ {{1等等。

通过该设计决策,实施非常简单:

GroupAdjacent