如何在ado.net中使用存储过程插入对象列表

时间:2013-11-04 17:04:09

标签: stored-procedures ado.net

假设我有这种方法

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中有对象吗?

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

为什么不使用Table-Valued Parameters将多行传递给存储过程。

  

使用用户定义的表类型声明表值参数。您可以使用表值参数将多行数据发送到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();