我有一个程序可以使用DataTable将一个巨大的SqlBulkCopy (2.000.000到70.000.000行,取决于配置)写入数据库。
我决定将填充此表的循环更改为IDataReader,因为行数通常会导致OutOfMemoryException。
表的填充方式如下
// int[] firsts;
// string[] seconds;
// byte[] thirds;
var table = new DataTable();
foreach(var f in firsts)
{
foreach(var s in seconds)
{
foreach(var t in thirds)
{
var row = table.NewRow();
row[0] = f;
row[1] = s;
row[2] = t;
table.Rows.Add(row);
}
}
// here I also bulk load the table and clear it
}因此,在我的IDataReader类中,我将按索引循环。这是我的尝试。
class TableReader : IDataReader
{
bool Eof = false;
int FirstIndex;
int SecondIndex;
int ThirdIndex;
//those are populated via constructor
int[] firsts;
string[] seconds;
byte[] thirds;
// this will be retrieved automatically via indexer
object[] Values;
public bool Read()
{
if(ThirdIndex != thirds.Length
&& SecondIndex < seconds.Length
&& FirstIndex < firsts.Length)
{
Values[0] = firsts[FirstIndex];
Values[1] = seconds[SecondIndex];
Values[2] = thirds[ThirdIndex++];
}
else if(SecondIndex != seconds.Length)
{
ThirdIndex = 0;
SecondIndex++;
}
else if(FirstIndex != firsts.Length)
{
SecondIndex = 0;
FirstIndex++;
}
else
{
Eof = true;
}
return !Eof;
}
}我使用带中断的while(true)循环而不是Eof创建了这段代码,但我似乎想不出如何做到这一点。
有人能帮忙吗?
发布于 2017-04-02 01:33:50
实际上,如果您实现了IDataReader并使用“产生返回”关键字来提供行,这实际上是可能的。IDataReader的实现有点麻烦,但它一点也不复杂。下面的代码可以调整为将一兆字节的数据加载到数据库中,并且不会耗尽内存。
https://stackoverflow.com/questions/42980028
复制相似问题