如何使用对象列表而不是循环填充SQL Server数据库

时间:2019-07-10 15:08:19

标签: c# sql sql-server wpf

我有来自Excel电子表格的数据,我无法更改它的输入方式。有没有一种解决方案,可以将IList<IList<Object>>值添加到SQL Server数据库中,而不是因为当前达到5k行而达到极限而循环。

我还得知我不应该使用注射剂,因此欢迎其他选择。

public static void Load_Table()
{
    // This function on_click populates the datagrid named JumpTable
    // this.JumpTable.ItemsSource = null; // Clears the current datagrid before getting new data
    // Pulls in the 2d table from the client sheet
    IList<IList<Object>> client_sheet = Get(SetCredentials(), "$placeholder", "Client!A2:AY");
    DBFunctions db = new DBFunctions();
    db.postDBTable("DELETE FROM Client");

    foreach (var row in client_sheet)
    {
        string exe = "INSERT INTO Client ([Tracker ID],[Request ID]) VALUES('" + row[0].ToString() + "','" + row[1].ToString() + "')";
        db.postDBTable(exe);
    }
}

数据库功能

public SqlConnection getDBConnection()
{
    // --------------< Function: Opens the connection to our database >-------------- \\
    string connectionString = Properties.Settings.Default.connection_string; // Gets the connection source from properties
    SqlConnection dbConnection = new SqlConnection(connectionString); // Creates the connection based off our source
    if (dbConnection.State != ConnectionState.Open) dbConnection.Open(); // If it's not already open then open the connection

    return dbConnection;
}
public DataTable getDBTable(string sqlText)
{
    // --------------< Function: Gets the table from our database >-------------- \\
    SqlConnection dbConnection = getDBConnection();

    DataTable table = new DataTable();
    SqlDataAdapter adapter = new SqlDataAdapter(sqlText, dbConnection);adapter.Fill(table);

    return table;
}

public void postDBTable(string sqlText)
{
    // --------------< Function: Post data to our database >-------------- \\
    SqlConnection dbConnection = getDBConnection();

    SqlCommand cmd = new SqlCommand(sqlText, dbConnection);cmd.ExecuteNonQuery();
}

1 个答案:

答案 0 :(得分:1)

过去,我曾处理过许多批量数据加载。避免使用SQL Server进行单个插入的主要方法有两种:一次插入值列表或使用批量插入。

使用值列表的第一个选项是这样的:

INSERT INTO Foo (Bar,Baz)
VALUES ('bar','baz'),
       ('anotherbar','anotherbaz')

在c#中,您将遍历列表并构建值内容,但是在没有sql注入漏洞的情况下很难做到这一点。

第二个选项是对SQL批量复制和datatable使用批量插入。在进入下面的代码之前,您需要构建一个DataTable来保存所有数据,然后使用SqlBulkCopy通过Sql功能插入行,该功能针对插入大量数据进行了优化。

using (var bulk = new SqlBulkCopy(con)
{
    //bulk mapping is a SqlBulkCopyColumnMapping[] and is not necessaraly needed if the DataTable matches your destination table exactly
    foreach (var i in bulkMapping)
    {
        bulk.ColumnMappings.Add(i);
    }

    bulk.DestinationTableName = "MyTable";

    bulk.BulkCopyTimeout = 600;
    bulk.BatchSize = 5000;

    bulk.WriteToServer(someDataTable);
}

这是两个框架包含的方法。还有其他可以提供帮助的库。 Dapper是其中之一,但我不确定它如何处理后端的插入。实体框架是另一个,但是它只插入一次,因此只是将问题从您的代码转移到其他代码。