Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NET高效调用存储过程_C#_Database_Stored Procedures_Ado.net_Bulkinsert - Fatal编程技术网

C# NET高效调用存储过程

C# NET高效调用存储过程,c#,database,stored-procedures,ado.net,bulkinsert,C#,Database,Stored Procedures,Ado.net,Bulkinsert,我有一个存储过程,它在DB表中插入/更新条目。 我还有一个web服务,需要每隔几秒钟将大量新更新传递到数据库中 我希望在不严重影响性能的情况下实现这一点,但是我不确定如何最好地解决这个问题 这是我的代码(尽可能简化) *注意:我使用datatable,因为存储过程使用的参数之一是来自DB的自定义用户定义的表类型 public class DBWorker { public void Update(IEnumerable<UpdateModel> updates) {

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

我希望在不严重影响性能的情况下实现这一点,但是我不确定如何最好地解决这个问题

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

*注意:我使用datatable,因为存储过程使用的参数之一是来自DB的自定义用户定义的表类型

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; }
}
公共类DBWorker
{
公共无效更新(IEnumerable更新)
{
使用(SqlConnection=newsqlconnection(this.\u connectionString))
使用(SqlCommand命令=新的SqlCommand(this.\u storedprocesdurestring,connection){CommandType=CommandType.storedprocesdure})
{
foreach(更新中的var更新)
{
Add(“@EntryID”,SqlDbType.Int).Value=update.EntryID;
command.Parameters.Add(“@Type”,SqlDbType.Int).Value=update.Type;
DataTable=新的DataTable();
dataTable.Columns.Add(“ParamID”);
dataTable.Columns.Add(“值”);
DataRow行=dataTable.NewRow();
行[“ParamID”]=update.ParamID;
行[“值”]=update.Value;
dataTable.Rows.Add(行);
command.Parameters.Add(“@NameValues”,SqlDbType.Structured).Value=dataTable;
command.ExecuteNonQuery();
}
}
}
}
公共类更新模型
{
public int EntryID{get;set;}
公共int类型{get;set;}
公共int参数{get;set;}
公共字符串值{get;set;}
}
我主要担心的是,上面的代码会对每个更新进行查询,如果我有很多更新,会大大降低我的DP。是否有任何方法可以在某种“批量”模式下调用存储过程

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

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

  • ID-int,identity,PK
  • EntryID-int,不为空
  • 类型-int,notnull
  • ParamID-int,notnull
  • 值-varchar,notnull

    • 你在这里走对了路,但是

    • 您将创建datatable,添加一行,并将datatable传递给存储过程。对于每个UpdateModel。最好在每次更新时创建一行(使用更新对象属性中的所有四列),然后将datatable(现在有许多行)传递给SP
    • 考虑一下该命令的执行情况——特别是您将如何添加参数(假设每次循环时都要添加参数)
    • 为datatable中的列指定一些显式数据类型

    • 对于更新序列,例如20,您希望有一个包含20行、4列的datatable,一个包含一个结构化参数的命令,并调用SP一次。

      您可能还希望在创建连接和命令之前打开连接并创建datatable。保持连接打开的时间最短。感谢您的帮助。我会牢记在心,看看我能做些什么。但有一个问题-你说的3是什么意思。“给出一些明确的数据类型”?我正在为每个命令params.Hi-Kobek指定SqlDbType。对但是DataTable中的列可以使用某些数据类型。如果您知道它们是什么,请指定它们。从逻辑上讲,SqlCommand只需要一个参数,但让列具有正确的数据类型总是很方便的。如果没有其他原因的话,你的代码会以一种明显的方式在早期失败,而不是以一种模糊的方式在稍后失败。太棒了,谢谢你的好提示。我将相应地编辑我的代码。再次感谢