ADO.NET有效地调用存储过程

时间:2018-05-03 12:14:00

标签: c# database stored-procedures ado.net bulkinsert

我有一个存储过程,可以在数据库表中插入/更新条目。 我还有一个Web服务,需要将大量新更新每隔几秒传递到数据库中。

我想在没有重大性能影响的情况下实现这一目标,但我不确定如何最好地解决这个问题。

这是我的代码(尽可能简化)

*注意:我使用数据表,因为存储过程使用的其中一个参数是来自数据库的自定义用户定义表类型

public class DBWorker
{
    public void Update(IEnumerable<UpdateModel> updates)
    {
        using (SqlConnection connection = new SqlConnection(this._connectionString))
        using (SqlCommand command = new SqlCommand(this._storedProcedureString, connection) { CommandType = CommandType.StoredProcedure })
        {
            foreach (var update in updates)
            {
                command.Parameters.Add("@EntryID", SqlDbType.Int).Value = update.EntryID;
                command.Parameters.Add("@Type", SqlDbType.Int).Value = update.Type;

                DataTable dataTable = new DataTable();
                dataTable.Columns.Add("ParamID");
                dataTable.Columns.Add("Value");
                DataRow row = dataTable.NewRow();
                row["ParamID"] = update.ParamID;
                row["Value"] = update.Value;
                dataTable.Rows.Add(row);

                command.Parameters.Add("@NameValues", SqlDbType.Structured).Value = dataTable;
                command.ExecuteNonQuery();
            }
        }
    }
}

public class UpdateModel
{
    public int EntryID { get; set; }

    public int Type { get; set; }

    public int ParamID { get; set; }

    public string Value { get; set; }
}

我主要担心的是上面的代码会对每次更新进行查询,如果我有很多更新,会大大减慢我的DP速度。有什么办法可以在某种“批量”模式下调用存储过程。

我正在考虑使用我的所有结果创建一个数据表,然后以某种方式将其传递给存储过程,但我不确定这是否会有实际的性能改进,也不知道如何实现它。

不确定它是否重要但这是SP实际更新的表的结构:

  • ID - int,identity,PK
  • EntryID - int,notnull
  • Type - int,notnull
  • ParamID - int,notnull
  • 值 - varchar,notnull

1 个答案:

答案 0 :(得分:1)

你走在正确的道路上,但是......

  1. 您正在创建数据表,添加单行,并将数据表传递给存储过程。对于每个UpdateModel。最好每次更新创建一行(包含所有四列 - 来自更新对象的属性),然后将数据表(现在有很多行)传递给SP。
  2. 想想这个命令发生了什么 - 特别是你可以添加的参数怎么样(假设你每次循环都重新添加参数)。
  3. 为数据表中的列提供一些显式数据类型
  4. 对于更新序列,例如20,您希望拥有一个包含20行,四列的数据表,一个带有一个结构化参数的命令,并调用SP一次。