1

假设我有这个方法

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 中的对象一样多之外是否有不同的解决方案?

感谢您的帮助

4

1 回答 1

0

为什么不使用表值参数将多行传递给存储过程。

表值参数是使用用户定义的表类型声明的。您可以使用表值参数将多行数据发送到 Transact-SQL 语句或例程(例如存储过程或函数),而无需创建临时表或许多参数。

  1. 创建类型

    Create Type TVP_LockPerformancesToDB As Table(
     UserId int, Comments varchar(50), [TimeStamp] datetime)
    
  2. 创建存储过程为

    CREATE PROCEDURE LockPerformancesToDB2
    @CommentInfo TVP_LockPerformancesToDB READONLY
    AS
    BEGIN
      INSERT INTO Performance
       (UserId, Comments, [TimeStamp])
        SELECT UserId, Comments, [TimeStamp]
      FROM @CommentInfo
    END
    
  3. 然后在你的代码中

    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();
    
于 2013-11-05T19:11:19.683 回答