C# NET高效调用存储过程
我有一个存储过程,它在DB表中插入/更新条目。 我还有一个web服务,需要每隔几秒钟将大量新更新传递到数据库中 我希望在不严重影响性能的情况下实现这一点,但是我不确定如何最好地解决这个问题 这是我的代码(尽可能简化) *注意:我使用datatable,因为存储过程使用的参数之一是来自DB的自定义用户定义的表类型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) {
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只需要一个参数,但让列具有正确的数据类型总是很方便的。如果没有其他原因的话,你的代码会以一种明显的方式在早期失败,而不是以一种模糊的方式在稍后失败。太棒了,谢谢你的好提示。我将相应地编辑我的代码。再次感谢