如何提高在 .NET windows 应用程序中保存多行的效率?

Posted

技术标签:

【中文标题】如何提高在 .NET windows 应用程序中保存多行的效率?【英文标题】:How to increase the efficiency for saving multiple rows in .NET windows application? 【发布时间】:2017-12-22 18:51:18 【问题描述】:

在我的 .NET Windows 应用程序中,我每次需要插入大约 1000 万条数据。但是,根据我效率低下的代码,保存到 SQL Server 需要超过 5 分钟。有没有最好的方法来减少时间保存那些数据?

private void saveAllDataInGrid()
    
        int rowCount = dataGridView1.RowCount;

        String str = "server=DESKTOP-TDV8JQ7;database=ExcelFileApp;Integrated Security=SSPI";
        SqlConnection con = new SqlConnection(str);
        con.Open();
        for (int count = 0; count < rowCount; count++)
        
            try
            
                String query = "insert into TemMainTable values (@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8,@p9,@p10,@p11,@p12,@p13,@p14,@p15,@p16,@p17,@p18,@p19,@p20,@p21,@p22,@p23)";
                SqlCommand cmd = new SqlCommand(query, con);

                cmd.Parameters.AddWithValue("@p1", dataGridView1.Rows[count].Cells[0].Value.ToString());
                cmd.Parameters.AddWithValue("@p2", dataGridView1.Rows[count].Cells[1].Value.ToString());
                cmd.Parameters.AddWithValue("@p3", dataGridView1.Rows[count].Cells[2].Value.ToString());
                cmd.Parameters.AddWithValue("@p4", dataGridView1.Rows[count].Cells[3].Value.ToString());
                cmd.Parameters.AddWithValue("@p5", dataGridView1.Rows[count].Cells[4].Value.ToString());
                cmd.Parameters.AddWithValue("@p6", dataGridView1.Rows[count].Cells[5].Value.ToString());
                cmd.Parameters.AddWithValue("@p7", dataGridView1.Rows[count].Cells[6].Value.ToString());
                cmd.Parameters.AddWithValue("@p8", dataGridView1.Rows[count].Cells[7].Value.ToString());
                cmd.Parameters.AddWithValue("@p9", dataGridView1.Rows[count].Cells[8].Value.ToString());
                cmd.Parameters.AddWithValue("@p10", dataGridView1.Rows[count].Cells[9].Value.ToString());
                cmd.Parameters.AddWithValue("@p11", dataGridView1.Rows[count].Cells[10].Value.ToString());
                cmd.Parameters.AddWithValue("@p12", dataGridView1.Rows[count].Cells[10].Value.ToString());
                cmd.Parameters.AddWithValue("@p13", dataGridView1.Rows[count].Cells[12].Value.ToString());
                cmd.Parameters.AddWithValue("@p14", dataGridView1.Rows[count].Cells[13].Value.ToString());
                cmd.Parameters.AddWithValue("@p15", dataGridView1.Rows[count].Cells[14].Value.ToString());
                cmd.Parameters.AddWithValue("@p16", dataGridView1.Rows[count].Cells[15].Value.ToString());
                cmd.Parameters.AddWithValue("@p17", dataGridView1.Rows[count].Cells[16].Value.ToString());
                cmd.Parameters.AddWithValue("@p18", dataGridView1.Rows[count].Cells[17].Value.ToString());
                cmd.Parameters.AddWithValue("@p19", dataGridView1.Rows[count].Cells[18].Value.ToString());
                cmd.Parameters.AddWithValue("@p20", dataGridView1.Rows[count].Cells[19].Value.ToString());
                cmd.Parameters.AddWithValue("@p21", dataGridView1.Rows[count].Cells[20].Value.ToString());
                cmd.Parameters.AddWithValue("@p22", dataGridView1.Rows[count].Cells[21].Value.ToString());
                cmd.Parameters.AddWithValue("@p23", dataGridView1.Rows[count].Cells[22].Value.ToString());

                int i = cmd.ExecuteNonQuery();

                lblDataSaved.Text = "No of rows Saved : " + rowCount;
            
            catch (Exception es)
            
                MessageBox.Show(es.Message);
            
        
        con.Close();
        MessageBox.Show("Successfully Saved");
    

谢谢!!

【问题讨论】:

1.在事务中执行此操作,2. 使用存储过程,3. 并行化代码 看:docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/… 看起来您正在将 datagridview 传输到 sql server 数据库中。 datagridview 上的数据从哪里来?你不能告诉我有人在 datagridview 中输入了 100 万行数据。 将多行插入 SQL Server 表的 .NET 最有效方法是使用 SqlBulkCopy 类。如果数据来自 Excel 文件,您可以从中获取数据读取器并调用 SqlBulkCopy.WriteToServer 【参考方案1】:

您可以使用User-Defined Table Types 进行批量插入。你需要在数据库SQL Server Management Studio &gt;&gt; Programability &gt;&gt; User-Defined Table Types中创建一个User-Defined Table Types

SQL 脚本语法将像这样创建User-Defined Table Types

CREATE TYPE [dbo].[TableList] AS TABLE(
    [SampleColumn1] [bigint] NOT NULL,
    [SampleColumn2] [nvarchar](100) NOT NULL    
)

示例 SQL 插入查询如下 -

INSERT  INTO SampleTable
        ( SampleColumn1 ,
          SampleColumn2

        )
        SELECT  cusTbl.SampleColumn1 ,
                cusTbl.SampleColumn2
        FROM    @TableList AS cusTbl;

在 C# 代码中 - 要插入的一般语法如下 -

SqlCommand cmd = new SqlCommand(query, con);    
var tvparam = cmd.Parameters.AddWithValue("@TableList", tableList);
tvparam.SqlDbType = SqlDbType.Structured;
tvparam.TypeName = "dbo.TableList" 
cmd.Connection.Open();
cmd.ExecuteNonQuery();

注意:您在 Windows 应用程序中使用了DataGridView。所以你可以很容易地传递你用来绑定DataGridViewDataTable。 注意DataTable 具有相同的ColumnNameDataType,它们在SQL Server 数据库User-Defined Table Types 中声明

我每次需要插入大约 1000 万条数据。但是,这需要超过 5 分钟 与将行一一发送到 SQL Server 相比,插入所花费的时间肯定会减少。 More Reading Here 和this Blog

【讨论】:

以上是关于如何提高在 .NET windows 应用程序中保存多行的效率?的主要内容,如果未能解决你的问题,请参考以下文章

如何从图像集合中保存视频文件?

如何在 Swift 应用程序中保存本地数据?

如何在更新 iphone 应用程序时从库目录中保留用户数据?

如何在核心数据中保存单个实体

如何在 android API 19 (KitKat) 中保持权限?

如何在 Vue CLI 4 和 Electron 项目中保护环境变量中的 API 密钥