【问题标题】:Taking rows in chunks from datatable and inserting in database从数据表中取出行并插入数据库
【发布时间】:2017-01-02 16:41:17
【问题描述】:

我在数据表中有大约 25k 条记录。我已经有以前的开发人员编写的更新查询,我无法更改。我正在尝试做的事情如下:

  1. 一次从数据表中获取 1000 条记录,记录可以从 1 到 25k 不等。
  2. 更新字符串中的查询,用这 1000 条记录替换其中的 IN('values here') 子句,然后对数据库进行查询。

现在,我知道有一些有效的方法可以做到这一点,例如使用数组绑定进行批量插入,但由于限制,我无法更改当前的编码模式。 我试图做的事情:

 if (dt.Rows.Count>0)
            {
                foreach (DataRow dr in dt.Rows)
                {

                    reviewitemsend =reviewitemsend + dr["ItemID"].ToString()+ ',';
                    //If record count is 1000 , execute against database. 
                }

            }

现在上面的方法让我不知所措,我很震惊。所以我想的另一种更好的方法如下:

int TotalRecords = dt.rows.count;
If (TotalRecords <1000 && TotalRecords >0 )
 //Update existing query with this records by placing them in IN cluse and execute
else
 {
        intLoopCounter = TotalRecords/1000; //Manage for extra records, as        counter will be whole number, so i will check modulus division also, if that is 0, means no need for extra counter, if that is non zero, intLoopCounter increment by 1
for(int i= 0;i < intLoopCounter; i++)
 {
    //Take thousand records at a time, unless last counter has less than 1000 records and execute against database
}

}

另外,注意更新查询如下:

 string UpdateStatement = @" UPDATE Table
 SET column1=<STATUS>,                                                       
 column2= '<NOTES>',
 changed_by = '<CHANGEDBY>',                                        
 status= NULL,   
 WHERE ID IN  (<IDS>)";

在上面的更新查询中,IDS 已经被所有 25K 记录 ID 替换,它将像这样显示给最终用户,内部只有我必须将它作为单独的块执行,所以在 IN() cluase 中我需要插入 1k一次记录

【问题讨论】:

标签: c# oracle datatable


【解决方案1】:

您可以使用以下 linq 方法拆分您的 Datatable

private static List<List<DataRow>> SplitDataTable(DataTable table, int pageSize)
{
    return
    table.AsEnumerable()
          .Select((row, index) => new { Row = row,  Index = index, })
          .GroupBy(x => x.Index / pageSize)
          .Select(x => x.Select(v => v.Row).ToList())
          .ToList();
}

然后对每个块运行数据库查询:

foreach(List<DataRow> chuck in SplitDataTable(dt, 1000))
{
    foreach(DataRow row in chuck)
    {
        // prepare data from row
    }

    // execute against database
}

提示:您可以修改拆分查询以直接在其中准备数据(通过替换 x.Select(v =&gt; v.Row) 部分,而不是在那个巨大的 DataTable 上循环两次。

【讨论】:

  • 让我测试一下。会回复你的
  • 是的,它工作正常,是的,我对其进行了优化以避免循环两次
猜你喜欢
  • 2017-05-16
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
相关资源
最近更新 更多