假设我有这种方法
public static void LockPerformanceToDB(List<performance> listOfPerformances)
{
//Do I need just to wrap this call with a loop? ...
using(var con = new OpenConnection)
{
//I call the LockPerformanceToDB SPROC here ...
}
}
我在数据库中也有这个程序:
CREATE PROCEDURE LockPerformancesToDB
@UserId INT,
@Comments VARCHAR(50),
@TimeStamp DATETIME
AS
BEGIN
INSERT INTO Performance
(UserId, Comments, [TimeStamp])
VALUES
(@UserId, @Comments, @TimeStamp)
END
这个sproc一次处理一次插入。很明显,列表中有几个相同的性能对象。循环遍历列表中的每个对象解决方案吗?
我想知道除了循环和调用sproc之外还有不同的解决方案,因为lisOfPerformances中有对象吗?
感谢您的帮助
答案 0 :(得分:0)
为什么不使用Table-Valued Parameters将多行传递给存储过程。
使用用户定义的表类型声明表值参数。您可以使用表值参数将多行数据发送到Transact-SQL语句或例程(例如存储过程或函数),而无需创建临时表或许多参数。
创建类型
Create Type TVP_LockPerformancesToDB As Table(
UserId int, Comments varchar(50), [TimeStamp] datetime)
将存储过程创建为
CREATE PROCEDURE LockPerformancesToDB2
@CommentInfo TVP_LockPerformancesToDB READONLY
AS
BEGIN
INSERT INTO Performance
(UserId, Comments, [TimeStamp])
SELECT UserId, Comments, [TimeStamp]
FROM @CommentInfo
END
然后在你的代码中
class Performance
{
public int UserId { get; set; }
public string Comments { get; set; }
public DateTime TimeStamp { get; set; }
}
List<Performance> listOfPerformances = new List<Performance>() {
new Performance{ UserId=1, Comments="First", TimeStamp=DateTime.Now},
new Performance{ UserId=2, Comments="Second", TimeStamp=DateTime.Now},
new Performance{ UserId=3, Comments="Third", TimeStamp=DateTime.Now}
};
SqlCommand cmd = new SqlCommand();
var dt = new DataTable();
dt.Columns.Add("UserId", typeof(Int32));
dt.Columns.Add("Comments", typeof(string));
dt.Columns.Add("TimeStamp", typeof(DateTime));
for (int i = 0; i < listOfPerformances.Count; i++)
{
dt.Rows.Add(listOfPerformances[i].UserId, listOfPerformances[i].Comments, listOfPerformances[i].TimeStamp);
}
cmd.Connection = conn;
cmd.CommandText = "LockPerformancesToDB2";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("CommentInfo", SqlDbType.Structured));
cmd.Parameters["CommentInfo"].Value = dt;
cmd.ExecuteNonQuery();