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