C# 绑定到数据库的自定义通用IEnumerator

C# 绑定到数据库的自定义通用IEnumerator,c#,sql,generics,ienumerable,C#,Sql,Generics,Ienumerable,我所做的工作包括从SQLServer数据库下载大量数据到内存中。为了实现这一点,我们使用SqlDataReader加载自定义数据集定义,然后遍历Datatable并将每一行构建到一个对象中,然后通常将这些对象打包到一个大型字典中 我们使用的数据量足够大,有时无法放入具有内存上限的单个数据表中。在最极端的情况下,这些词典甚至已经足够大,超过8GB的系统内存。我的任务是修复数据表溢出时抛出的outofmemory异常。为此,我实现了一个批处理方法,该方法似乎与数据表的使用方式相冲突,但它暂时起作用

我所做的工作包括从SQLServer数据库下载大量数据到内存中。为了实现这一点,我们使用SqlDataReader加载自定义数据集定义,然后遍历Datatable并将每一行构建到一个对象中,然后通常将这些对象打包到一个大型字典中

我们使用的数据量足够大,有时无法放入具有内存上限的单个数据表中。在最极端的情况下,这些词典甚至已经足够大,超过8GB的系统内存。我的任务是修复数据表溢出时抛出的outofmemory异常。为此,我实现了一个批处理方法,该方法似乎与数据表的使用方式相冲突,但它暂时起作用

我现在的任务是进一步降低这个过程的内存需求。我的想法是创建一个继承自IEnumerator的泛型类,该类接受SqlDataReader,基本上使用该读取器作为枚举的集合。MoveNext()函数将使读取器前进,当前属性将从读取器的当前行返回从生成器方法生成的指定类型化对象

我的问题是:这是一个可行的想法吗?我从未听说过/在网上找不到类似的东西

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


我愿意接受批评和惩罚,因为我想出了一个愚蠢的想法。我最感兴趣的是找到实现总体目标的最佳实践

使用迭代器块似乎相当合理,实际上非常简单:

private static IEnumerable<Foo> WrapReader(SqlDataReader reader)
{
    while (reader.Read())
    {
        Foo foo = ...; // TODO: Build a Foo from the reader
        yield return foo;
    }
}
如果小心,甚至可以使用LINQ来创建对象:

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