Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从datatable中分块获取行并插入数据库_C#_Oracle_Datatable - Fatal编程技术网

C# 从datatable中分块获取行并插入数据库

C# 从datatable中分块获取行并插入数据库,c#,oracle,datatable,C#,Oracle,Datatable,我在datatable中有大约25k条记录。我已经有以前的开发人员编写的更新查询,我无法更改。我想做的是: 每次从datatable中获取1000条记录,记录的范围从1到25k不等 更新字符串中的查询,用这1000条记录替换其中的in('values here')子句,并对数据库发起查询 现在,我知道有一些有效的方法可以做到这一点,比如使用数组绑定进行大容量插入,但由于限制,我无法更改当前的编码模式。 我试图做的是: if (dt.Rows.Count>0) {

我在datatable中有大约25k条记录。我已经有以前的开发人员编写的更新查询,我无法更改。我想做的是:

  • 每次从datatable中获取1000条记录,记录的范围从1到25k不等
  • 更新字符串中的查询,用这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
    }
    
    inttotalrecords=dt.rows.count;
    如果(总计记录0)
    //通过将这些记录放入cluse并执行,使用这些记录更新现有查询
    其他的
    {
    intLoopCounter=TotalRecords/1000;//管理额外记录,因为计数器将是整数,所以我也将检查模数除法,如果为0,表示不需要额外的计数器,如果为非零,intLoopCounter将增加1
    对于(int i=0;i
    }

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

     string UpdateStatement = @" UPDATE Table
     SET column1=<STATUS>,                                                       
     column2= '<NOTES>',
     changed_by = '<CHANGEDBY>',                                        
     status= NULL,   
     WHERE ID IN  (<IDS>)";
    
    stringupdatestatement=@“更新表”
    设置column1=,
    第2列=“”,
    将_更改为=“”,
    状态=空,
    其中ID位于()”;
    

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

    您可以使用此linq方法拆分您的
    数据表

    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();
    }
    
    private static List SplitDataTable(DataTable,int pageSize)
    {
    返回
    表1.AsEnumerable()
    .Select((行,索引)=>new{row=row,index=index,})
    .GroupBy(x=>x.索引/页面大小)
    .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
    }
    
    foreach(在SplitDataTable(dt,1000)中列出卡盘)
    {
    foreach(卡盘中的数据行)
    {
    //从行中准备数据
    }
    //对数据库执行
    }
    

    提示:您可以修改拆分查询以直接在其中准备数据(通过替换
    x.Select(v=>v.Row)
    部分,不要在巨大的
    数据表上循环两次

    请参考下面的链接。我想这是您想要的。这种方法在数据库中,我正在寻找C#DataTable让我测试一下。我会回复您是的,它工作正常,是的,我优化它以避免循环两次