我目前正在呼叫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
}
}
答案 0 :(得分:3)
Read
和NextResult
方法将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 GroupBy
,MoreLINQ {{1等等。
通过该设计决策,实施非常简单:
GroupAdjacent