.net 序列或批处理项目DataGridView
我有940000行的大DataGridView…哎哟,从分析csv文件填充,DataGridView有一个名为序列号1到940000的列。我试图做的是对序列进行重新编号,以将DataGridView中的行数拆分为1到7000的序列。对序列列重新排序最有效的方法是什么.net 序列或批处理项目DataGridView,.net,vb.net,datagridview,.net,Vb.net,Datagridview,我有940000行的大DataGridView…哎哟,从分析csv文件填充,DataGridView有一个名为序列号1到940000的列。我试图做的是对序列进行重新编号,以将DataGridView中的行数拆分为1到7000的序列。对序列列重新排序最有效的方法是什么 Using reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(fileName) reader.TextFieldType = FileIO.Fie
Using reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(fileName)
reader.TextFieldType = FileIO.FieldType.Delimited
reader.SetDelimiters(",")
Dim currentRow As String()
Dim serial As String
Dim sequence As Integer = 0
Dim RollId As String
'pbUploadFile.Maximum = serialAmmount / quantityBreak
pbUploadFile.Maximum = serialAmmount
pbUploadFile.Step = 1
pbUploadFile.Value = 0
For i = 1 To serialAmmount / quantityBreak
For j = 1 To quantityBreak
Try
currentRow = reader.ReadFields()
serial = currentRow(0).ToString
sequence += 1
EnterDataIntoDatabase(serial, sequence, nextRollNumber, ddSelectPartNumber.Text)
pbUploadFile.Increment(1)
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Code " & ex.Message & "is not valid and will be skipped check csv file")
End Try
Next j
sqlCmd = New SqlClient.SqlCommand("SELECT * FROM serials WHERE Sequence=@sequence AND RollNo=@rollNo ", sqlCon)
sqlCmd.CommandType = CommandType.Text
sqlCmd.Parameters.AddWithValue("@sequence", 1)
sqlCmd.Parameters.AddWithValue("@rollNo", nextRollNumber)
sqlCon.Open()
Dim readRollId As SqlClient.SqlDataReader = sqlCmd.ExecuteReader()
If readRollId.Read() Then
RollId = readRollId.Item("Code")
End If
sqlCon.Close()
UpdateAvailableRolls(ddSelectPartNumber.Text, nextRollNumber, RollId)
nextRollNumber += 1
UpdateRollNo(nextRollNumber)
sequence = 0
'pbUploadFile.Increment(1)
Next i
SaveFile()
End Using
通常最好考虑如何使用数据,以及在决定如何做某事以及使用什么工具来做某事时如何使用数据。没有一种正确、快速、有效的方式来做大多数事情 也就是说,做事情有一些不好的方式。使用
DataGridView
作为数据容器似乎是不明智的(尽管我在代码中看不到任何与DGV相关的内容)。A) 数据没有自动进入的方式-您必须编写代码才能进入,2)数据没有自动进入其他地方的方式-您必须编写代码来循环通过它并将数据提取出来。然后是所有数据都可能存储为字符串的问题
看起来还有更多的事情要做,而不仅仅是分批处理项目。下面将从CSV导入行,处理它们并将它们写回DB(我使用的是MySql,但概念是相同的)
首先,
TextFieldParser
是一个非常方便的工具,但它有一个主要缺点,即它只返回字符串。如果CSV中包含价格、日期、布尔值等,则该类型将丢失。在许多情况下,CSVHelper将是一个更好的选择
在本例中,由于数据是发送给数据库的,因此我将使用OleDB将CSV读入数据表
,对其进行批处理,然后将其发送到数据库
使用OleDB导入数据
Schema.INI
OleDb包含一个文本文件驱动程序,可用于解析CSV。它可以根据前几行的上下文“猜测”数据类型,但也可以定义它们。在CSV所在的文件夹/目录中,创建一个名为Schema.INI
的新文本文件。按如下方式定义CSV和列:
[Capitals.Csv]ColNameHeader=True
Format=CSVDelimited
textdimiter=
小数符号=。
CurrencySymbol=$
Col1=“Country”文本宽度254
Col2=“首都”文本宽度254
Col3=“总体”单个
Col4=“Rank”整数
Col5=“国庆节”日期
- 在一个文件中可以有多个csv定义,每个定义都以
[…]
将是CSV的名称[…]
- 如果CSV有标题行,则可以将其用作列名
- 如果列也用引号括起来(“像这样”、“在”、“csv中”),请使用
textdimiter=“
- 每个
条目定义数据类型并可以覆盖名称。这允许您将CSV中名为“Foo”的列“映射”到DB中名为“Bar”的列Col#=
- 可以指定其他选项,如十进制和货币符号以及文件中使用的代码页
ACEImportStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='{0}';Extended Properties='TEXT'"
<代码>数据源<代码>将是CSV和Schema.INI都存在的文件夹,“text”元素告诉它使用文本驱动程序。使用文件夹名填写空白:
ACEImportConnStr = String.Format(ACEImportConnStr, "C:\Temp")
OLEDB.12有时可能很挑剔,如果您有问题,请使用Microsoft.Jet.OLEDB.4.0作为提供程序
现在,要加载数据,只需从CSV文件名(无文件夹)中选择:
DataAdapter
将读取定义的模式,并在几秒钟内将CSV加载到数据表中。处理其他任务还有很多工作要做,但这就是概念
Dim sSQL = "SELECT * FROM YOUR_CSVFILE_NAME.CSV"
Dim sw As New Stopwatch
Dim rowsLoaded As Int32
Dim rowsUpdated As Int32
sw.Start()
ACEImportConnStr = String.Format(ACEImportConnStr, "C:\Temp")
' create Destination MySQL conn, Src and Dest dataadapters,
' and a command builder (because I am lazy...and fallible)
Using mysqlCon As New MySqlConnection(MySQLConnStr),
daSrc As New OleDbDataAdapter(sSQL, ACEImportConnStr),
daDest As New MySqlDataAdapter("SELECT * FROM Sample", mysqlCon),
cb As New MySqlCommandBuilder(daDest)
' important!
daSrc.AcceptChangesDuringFill = False
dtSample = New DataTable
rowsLoaded = daSrc.Fill(dtSample)
' csv lacks an ID column - add it
Dim dc As New DataColumn("Id", GetType(Int32))
dc.DefaultValue = 1
dtSample.Columns.Add(dc)
dc.SetOrdinal(0)
' MY csv also lacks a BATCH column
dc = New DataColumn("Batch", GetType(Int32))
dc.DefaultValue = 1
dtSample.Columns.Add(dc)
dc.SetOrdinal(1)
' set the batch number
' each 5k rows == a batch
Dim batch As Int32 = 1
Dim counter As Int32 = 1
For Each dr As DataRow In dtSample.Rows
dr("Batch") = batch
counter += 1
If counter > 5000 Then
counter = 0
batch += 1
End If
Next
' now save the data to MySQL
mysqlCon.Open()
' inserting 250k rows takes a while,
' use a transaction
Using t As MySqlTransaction = mysqlCon.BeginTransaction
rowsUpdated = daDest.Update(dtSample)
t.Commit()
End Using
End Using
' show the IMPORT in a dgv
dgv1.DataSource = dtSample
dgv1.Columns("Id").Visible = False
' report
sw.Stop()
Console.WriteLine(sw.ElapsedMilliseconds)
原理很简单:因为数据绑定到一个DB,所以尽快将数据放入一个DataTable
中。这里的诀窍是有两个DB提供者参与:OleDB读取csv,MySql保存
- 通常,当DataAdapter填充
数据表时,所有行都设置为Unchanged
AcceptChangesDuringFill=False
将状态设置为Added
,以便MySql适配器可以插入这些行
- CommandBuilder通过SELECT命令生成要使用的INSERT SQL
- 我不知道serials rollno查询在做什么,但我不会在导入过程循环中运行查询。如果需要设置的某些值依赖于数据库中的值,请将它们加载到另一个DT中并从那里查询。有一些DataTable扩展方法使查找行变得容易
- 同样,我不知道
EnterDataIntoDatabase
做什么,但您应该努力处理和准备DataTable
中所有导入的数据,然后立即更新所有数据
你似乎有更多的事情要做,而不仅仅是对一堆行进行批处理或排序。上面的代码可以在1.2分钟内(几乎每秒3500行)导入250k行,分配批处理号,并将250k新行插入MySql
如果batch/sequencer与CSV中的每个X行的顺序类似,那么您可能一次只需加载7000行,设置值,保存该批,然后加载接下来的7k行。这将限制每次加载的行数,并减少应用程序使用的内存。但我不确定它是否适用
参考:
- 在MSDN上
有效的方法是将数据存储在列表或数据表中,然后处理数据,而不是用户的视图。您是否在填充数据时设置了顺序?在加载数据时可以这样做吗?(标题与其余部分不匹配).Hi PUROTIX序列来自csv文件,该文件有两列序列号,序列号从1到940000。我试图将其分解为1到7000。我使用了数据
Dim sSQL = "SELECT * FROM YOUR_CSVFILE_NAME.CSV"
Dim sw As New Stopwatch
Dim rowsLoaded As Int32
Dim rowsUpdated As Int32
sw.Start()
ACEImportConnStr = String.Format(ACEImportConnStr, "C:\Temp")
' create Destination MySQL conn, Src and Dest dataadapters,
' and a command builder (because I am lazy...and fallible)
Using mysqlCon As New MySqlConnection(MySQLConnStr),
daSrc As New OleDbDataAdapter(sSQL, ACEImportConnStr),
daDest As New MySqlDataAdapter("SELECT * FROM Sample", mysqlCon),
cb As New MySqlCommandBuilder(daDest)
' important!
daSrc.AcceptChangesDuringFill = False
dtSample = New DataTable
rowsLoaded = daSrc.Fill(dtSample)
' csv lacks an ID column - add it
Dim dc As New DataColumn("Id", GetType(Int32))
dc.DefaultValue = 1
dtSample.Columns.Add(dc)
dc.SetOrdinal(0)
' MY csv also lacks a BATCH column
dc = New DataColumn("Batch", GetType(Int32))
dc.DefaultValue = 1
dtSample.Columns.Add(dc)
dc.SetOrdinal(1)
' set the batch number
' each 5k rows == a batch
Dim batch As Int32 = 1
Dim counter As Int32 = 1
For Each dr As DataRow In dtSample.Rows
dr("Batch") = batch
counter += 1
If counter > 5000 Then
counter = 0
batch += 1
End If
Next
' now save the data to MySQL
mysqlCon.Open()
' inserting 250k rows takes a while,
' use a transaction
Using t As MySqlTransaction = mysqlCon.BeginTransaction
rowsUpdated = daDest.Update(dtSample)
t.Commit()
End Using
End Using
' show the IMPORT in a dgv
dgv1.DataSource = dtSample
dgv1.Columns("Id").Visible = False
' report
sw.Stop()
Console.WriteLine(sw.ElapsedMilliseconds)