Um exemplo de uso do IEnumerable SqlDataRecord
Funciona como um leitor de dados reverso
Observe que eu classifico. Isso é pelo índice clusterizado. A fragmentação dos índices matará absolutamente a velocidade de carregamento. A primeira implementação usou Insert Values (unsorted) e em uma execução de 12 horas esta versão é literalmente 100x mais rápida. Também desabilito outros índices além do PK e reindexo no final do carregamento. Em um longo prazo estou recebendo cerca de 500 linhas/segundo. Sua amostra é 1400/segundo tão grande. Se você começar a ver degradação, então coisas para olhar.
public class DocFTSinXsCollection : List<DocFTSinX>, IEnumerable<SqlDataRecord>
{
// used by TVP for fast insert
private int sID;
private IEnumerable<DocFTSinX> docFTSinXs;
IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
{
//todo fix the order in 3 to sID, wordID1, workID2
var sdr = new SqlDataRecord(
new SqlMetaData("wordID1", System.Data.SqlDbType.Int),
new SqlMetaData("wordID2", System.Data.SqlDbType.Int),
new SqlMetaData("sID", System.Data.SqlDbType.Int),
new SqlMetaData("Delta", System.Data.SqlDbType.Int));
foreach (DocFTSinX oh in docFTSinXs.OrderBy(x => x.Word1).ThenBy(x => x.Word2))
{
sdr.SetInt32(0, oh.Word1);
sdr.SetInt32(1, oh.Word2);
sdr.SetInt32(2, sID);
sdr.SetInt32(3, (Int32)oh.Delta);
yield return sdr;
}
}
public DocFTSinXsCollection(int SID, IEnumerable<DocFTSinX> DocFTSinXs)
{
sID = SID;
docFTSinXs = DocFTSinXs;
//Debug.WriteLine("DocFTSinXsCollection DocFTSinXs " + DocFTSinXs.Count().ToString());
}
}
Outras ferramentas a serem consideradas são a classe SQLBulkCopy .NET e o Drapper.
OP perguntou como executar em lotes.
while (true)
{
// if no more break;
// fill list or datatable with next 100000
// send list or datatable to db
}