从C#更新大量行的有效方法

时间:2016-06-01 17:14:24

标签: c# sql-server linq

我有一个程序,我打开一个SqlConnection,加载一个对象列表,修改每个对象的值,然后更新SQL Server数据库中的行。因为修改需要字符串解析,所以我无法使用纯T-SQL。

现在我循环遍历对象列表,并在每次迭代中运行SQL更新。这似乎效率低下,我想知道是否有更有效的方法来使用LINQ

该列表名为UsageRecords。我更新的值为MthlyConsumption

这是我的代码:

foreach (var item in UsageRecords)
{
    string UpdateQuery = @"UPDATE tbl810CTImport 
                           SET MthlyConsumption = " + item.MthlyConsumption +
                           "WHERE ID = " + item.Id;
    SqlCommand update = new SqlCommand(UpdateQuery, sourceConnection);
    update.ExecuteNonQuery();
}

4 个答案:

答案 0 :(得分:2)

请改为尝试:

string UpdateQuery = @"UPDATE tbl810CTImport SET MthlyConsumption = @consumption WHERE ID = @itemId";
var update = new SqlCommand(UpdateQuery, sourceConnection);
update.Parameters.Add("@consumption", SqlDbType.Int); // Specify the correct types here
update.Parameters.Add("@itemId", SqlDbType.Int); // Specify the correct types here
foreach (var item in UsageRecords)
{
    update.Parameters[0].Value = item.MthlyConsumption; 
    update.Parameters[1].Value = item.Id;
    update.ExecuteNonQuery();
}

它应该更快,因为:

  • 您不必每次都创建命令。
  • 每次都不创建新字符串(连接)
  • 每次迭代都不会解析查询(只需更改参数值)。
  • 它将cache the execution plan。 (感谢评论中的@JohnCarpenter)

答案 1 :(得分:2)

您可以使用

  1. post - 请参阅SqlDataAdapter
  2. 或我以前做过的是以下之一:

    1. 删除有问题的ID,并重新制作
      1. 批量将ID +新值插入登台表,并更新SQL服务器上的表:
      2. update u set u.MthlyConsumption = s.MthlyConsumption from tbl810CTImport u inner join staging s on u.id = s.id

答案 2 :(得分:0)

在这样的情况下,如果您不能编写单个更新语句来涵盖所有基础,那么批量处理语句并一次运行多个语句是个好主意。

var commandSB = new StringBuilder();
int batchCount = 0;

using (var updateCommand = sourceConnection.CreateCommand())
{
    foreach (var item in UsageRecords)
    {
        commandSB.AppendFormat(@"
            UPDATE tbl810CTImport 
            SET MthlyConsumption = @MthlyConsumption{0}
            WHERE ID = @ID{0}", 
            batchCount
        );

        updateCommand.Parameters.AddWithValue(
            "@MthlyConsumption" + batchCount,
            item.MthlyConsumption
        );

        updateCommand.Parameters.AddWithValue(
            "@ID" + batchCount,
            item.MthlyConsumption
        );

        if (batchCount == 500) {
            updateCommand.CommandText = commandSB.ToString();
            updateCommand.ExecuteNonQuery();

            commandSB.Clear();
            updateCommand.Parameters.Clear();
            batchCount = 0;
        }
        else {
            batchCount++;
        }
    }

    if (batchCount != 0) {
        updateCommand.ExecuteNonQuery();
    }
}

答案 3 :(得分:0)

应该这么简单。 。 。

private void button1_Click(object sender, EventArgs e)
        {
            SqlConnection con = new SqlConnection("Server=YourServerName;Database=YourDataBaseName;Trusted_Connection=True"); 

            try
            {
                //cmd new SqlCommand( "UPDATE Stocks 
                //SET Name = @Name, City = @cit Where FirstName = @fn and LastName = @add";

                cmd = new SqlCommand("Update Stocks set Ask=@Ask, Bid=@Bid, PreviousClose=@PreviousClose, CurrentOpen=@CurrentOpen Where Name=@Name", con);
                cmd.Parameters.AddWithValue("@Name", textBox1.Text);
                cmd.Parameters.AddWithValue("@Ask", textBox2.Text);
                cmd.Parameters.AddWithValue("@Bid", textBox3.Text);
                cmd.Parameters.AddWithValue("@PreviousClose", textBox4.Text);
                cmd.Parameters.AddWithValue("@CurrentOpen", textBox5.Text);
                con.Open();
                int a = cmd.ExecuteNonQuery();
                if (a > 0)
                {
                    MessageBox.Show("Data Updated");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                con.Close();
            }
        }

更改代码以满足您的需求。