如何使用SqlBulkCopy将数百万行插入到数据库中?

How can I insert millions of rows into a database fast then using SqlBulkCopy?

I read form file more than a million lines and try to add it to a database. In a normal way, its take too much time... So I am using Insert 2 million rows into SQL Server quickly

the rows are not the same every time. some time in the file the column numbers of "Aux" and "MUn' can be between 0 to 16. So I must make it work for any situation. It takes about 20-30 seconds this way... There is the faster way to do it? Or there is way to optimize my method? Thanks...

This is my database :

CREATE TABLE [dbo].[TestResults] (
    [RecId]     BIGINT        NOT NULL,
    [CycId]     INT           NOT NULL,
    [Step]      INT           NOT NULL,
    [Test_time] FLOAT (53)    NOT NULL,
    [Step_min]  FLOAT (53)    NOT NULL,
    [Amp_hour]  FLOAT (53)    NOT NULL,
    [Watt_hour] REAL          NOT NULL,
    [Amps]      FLOAT (53)    NOT NULL,
    [Volts]     REAL          NOT NULL,
    [State]     NVARCHAR (5)  NOT NULL,
    [ES]        INT           NOT NULL,
    [DPt_time]  NVARCHAR (50) NOT NULL,
    [Aux1]      REAL          NULL,
    [MUn1]      NVARCHAR (10) NULL,
    [Aux2]      REAL          NULL,
    [MUn2]      NVARCHAR (10) NULL,
    [Aux3]      REAL          NULL,
    [MUn3]      NVARCHAR (10) NULL,
    [Aux4]      REAL          NULL,
    [MUn4]      NVARCHAR (10) NULL,
    [Aux5]      REAL          NULL,
    [MUn5]      NVARCHAR (10) NULL,
    [Aux6]      REAL          NULL,
    [MUn6]      NVARCHAR (10) NULL,
    [Aux7]      REAL          NULL,
    [MUn7]      NVARCHAR (10) NULL,
    [Aux8]      REAL          NULL,
    [MUn8]      NVARCHAR (10) NULL,
    [Aux9]      REAL          NULL,
    [MUn9]      NVARCHAR (10) NULL,
    [Aux10]     REAL          NULL,
    [MUn10]     NVARCHAR (10) NULL,
    [Aux11]     REAL          NULL,
    [MUn11]     NVARCHAR (10) NULL,
    [Aux12]     REAL          NULL,
    [MUn12]     NVARCHAR (10) NULL,
    [Aux13]     REAL          NULL,
    [MUn13]     NVARCHAR (10) NULL,
    [Aux14]     REAL          NULL,
    [MUn14]     NVARCHAR (10) NULL,
    [Aux15]     REAL          NULL,
    [MUn15]     NVARCHAR (10) NULL,
    [Aux16]     REAL          NULL,
    [MUn16]     NVARCHAR (10) NULL
);

this is my code :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TEST__
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string tableName = "TestResults";
        private DataTableReader dataTableReader;

        private void run() {

            string[] arr = File.ReadAllLines(Globals.filePath);
            int aux = Regex.Matches(arr[1], "Aux").Count;

            using (SqlConnection connection =
                    new SqlConnection(Globals.connString))
            {
                SqlBulkCopy bulkCopy =
                    new SqlBulkCopy
                    (
                    connection,
                    SqlBulkCopyOptions.TableLock |
                    SqlBulkCopyOptions.FireTriggers |
                    SqlBulkCopyOptions.UseInternalTransaction,
                    null
                    );

                bulkCopy.DestinationTableName = tableName;
                connection.Open();
                DataTable dataTable = new DataTable(tableName);

                dataTable.Columns.Add("RecId");
                dataTable.Columns.Add("CycId");
                dataTable.Columns.Add("Step");
                dataTable.Columns.Add("Test_time");
                dataTable.Columns.Add("Step_min");
                dataTable.Columns.Add("Amp_hour");
                dataTable.Columns.Add("Watt_hour");
                dataTable.Columns.Add("Amps");
                dataTable.Columns.Add("Volts");
                dataTable.Columns.Add("State");
                dataTable.Columns.Add("ES");
                dataTable.Columns.Add("DPt_time");
                for (int i = 1; i <= aux; i++)
                {
                    dataTable.Columns.Add($"Aux{i}");
                    dataTable.Columns.Add($"MUn{i}");
                }


                for (int i = 2; i < arr.Count(); i++)
                {
                    string[] param = arr[i].Split('\t');

                    DataRow row = dataTable.NewRow();
                    row["RecId"] = param[0];
                    row["CycId"] = param[1];
                    row["Step"] = param[2];
                    row["Test_time"] = param[3];
                    row["Step_min"] = param[4];
                    row["Amp_hour"] = param[5];
                    row["Watt_hour"] = param[6];
                    row["Amps"] = param[7];
                    row["Volts"] = param[8];
                    row["State"] = param[9];
                    row["ES"] = param[10];
                    row["DPt_time"] = param[11];
                    for (int j = 0, k = 1; k <= aux; j += 2, k++)
                    {
                        row[$"Aux{k}"] = param[12 + j];
                        row[$"MUn{k}"] = param[13 + j];
                    }
                    dataTable.Rows.Add(row);
                }

                dataTableReader = new DataTableReader(dataTable);

                bulkCopy.WriteToServer(dataTableReader);
                connection.Close();
            }
        }


        private void button1_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            run();
            stopwatch.Stop();
            MessageBox.Show(stopwatch.ElapsedMilliseconds.ToString());
        }
    }
}