2012-08-08 131 views
2

我所做的工作涉及到从SQL服务器数据库中下载大量数据。为此,我们使用SqlDataReader加载自定义数据集定义,然后遍历Datatable并将每行构建到一个对象中,然后通常将这些对象打包为一个大型字典。自定义通用IEnumerator绑定到数据库

我们使用的数据量足够大,有时无法放入具有内存上限的单个数据表。在极端情况下,字典甚至已经增长到足以超过8 GB的系统内存。我负责修复数据表溢出时引发的内存异常。我通过实现批处理方法来实现这一点,该方法似乎与数据表的使用方式有冲突,但它暂时有效。

我现在的任务是进一步减少这个过程的内存需求。我的想法是创建一个一般类型的继承自IEnumerator的类,它接受一个SqlDataReader并基本上使用阅读器作为它正在枚举的集合。 MoveNext()函数将推进阅读器,并且Current属性将从阅读器的当前行返回由构建器方法构建的指定类型的对象。

我的问题:这是一个可行的想法?我从来没有听说过/无法在网上找到任何喜欢它的东西。

另外,逻辑上:当我调用当前属性时,如何调用类型声明要求的特定构建器函数?

我很乐意批评和批评梦想的一个愚蠢的想法。我最想找到实现总体目标的最佳做法。

回答

3

看起来相当明智的,实际上非常简单使用迭代器块:

private static IEnumerable<Foo> WrapReader(SqlDataReader reader) 
{ 
    while (reader.Read()) 
    { 
     Foo foo = ...; // TODO: Build a Foo from the reader 
     yield return foo; 
    } 
} 

然后你可以使用它:

using (SqlDataReader reader = ...) 
{ 
    foreach (Foo foo in WrapReader(reader)) 
    { 
     ... 
    } 
} 

如果你细心的话你甚至可以使用LINQ到对象:

using (SqlDataReader reader = ...) 
{ 
    var query = from foo in WrapReader(reader) 
       where foo.Price > 100 
       select foo.Name; 
    // Use the query... 
} 
+0

我想我应该在你的书中读到第6章... :) – Jared275 2012-08-08 15:57:51

+0

@ Jared275:Soun ds对我很好:) – 2012-08-08 15:58:35

相关问题