2015-10-26 96 views
1

我想插入一個對象列表到sql server表中。但是,目前,我必須在每次插入記錄行時打開和關閉sql連接。將對象列表插入到SQL Server表中

我只是想知道是否有一種方法可以一次插入記錄列表中的所有對象?這是代碼片段。

public void InsertDataToDb() 
{ 
    string connectionString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString; 
    var records = GetRecords(); 

    using (SqlConnection conn = new SqlConnection(connectionString)) 
    { 
     SqlCommand cmd = 
      new SqlCommand(
       "INSERT INTO TableName (param1, param2, param3) VALUES (@param1, @param2, @param3)"); 
     cmd.CommandType = CommandType.Text; 
     cmd.Connection = conn; 
     foreach (var item in records) 
     { 
      cmd.Parameters.AddWithValue("@param1", item.param1); 
      cmd.Parameters.AddWithValue("@param2", item.param2); 
      cmd.Parameters.AddWithValue("@param3", item.param3); 

      conn.Open(); 
      cmd.ExecuteNonQuery(); 
      cmd.Parameters.Clear(); 
      conn.Close(); 
     } 
    } 
} 
+0

你可以一個查詢中添加多行。只要確保參數是唯一的。 –

+0

另一種方法是創建一個帶表值參數的存儲過程 –

+0

@JeroenvanLangen但是如果我在列表中有100條記錄,我該如何逐個添加? – catlovespurple

回答

6

我做假設你的數據類型(改變它們,因爲你需要,根據實際DbTypes是什麼),但這樣的事情應該這樣做:

public void InsertDataToDb() 
    { 
     string connectionString = ConfigurationManager.ConnectionStrings["connection"]. 
      ConnectionString; 
     var records = GetRecords(); 

     using (SqlConnection conn = new SqlConnection(connectionString)) 
     { 
      conn.Open(); 

      SqlCommand cmd = 
       new SqlCommand(
        "INSERT INTO TableName (param1, param2, param3) " + 
        " VALUES (@param1, @param2, @param3)"); 
      cmd.CommandType = CommandType.Text; 
      cmd.Connection = conn; 
      cmd.Parameters.Add("@param1", DbType.String); 
      cmd.Parameters.Add("@param2", DbType.String); 
      cmd.Parameters.Add("@param3", DbType.String); 

      foreach (var item in records) 
      { 
       cmd.Parameters[0].Value = item.param1; 
       cmd.Parameters[1].Value = item.param2; 
       cmd.Parameters[2].Value = item.param3; 

       cmd.ExecuteNonQuery(); 
      } 

      conn.Close(); 
     } 
    } 

我還建議調用一個事務,以便所有100個插入可以作爲單個事務完成。

- 編輯 -

關於交易,這裏是你如何將其添加:

conn.Open(); // already there -- to show you where to start the transaction 

SqlTransaction trans = conn.BeginTransaction(); 
string sql = "INSERT INTO TableName (param1, param2, param3) " + 
    "VALUES (@param1, @param2, @param3)"; 

SqlCommand cmd = new SqlCommand(sql, conn, trans); 

然後,您關閉連接之前(或者在交易的最後陳述後, ,其中可以包括選擇,更新,等等):

trans.Commit(); 
+0

感謝您的回答。他們工作得很好。我想知道你推薦的交易是編寫一個T-Store程序來同時完成所有這些工作? – catlovespurple

+0

不,ADO.net內部的交易......我沒有編譯/測試這個,也不想冒着在交易中犯錯的風險,但這很容易。我會解決它並告訴你我的意思。 – Hambone

+1

根據您的更新,您可以將該事務封裝在'using'語句中,這是一種簡單的方法,可以確保事務在未調用Commit()的情況下離開該範圍時得到回滾。然而,因爲無論如何連接都被關閉了,這並不重要。 –

3

你可以使用像Dapper

的ORM

有了這個庫,你可以寫這樣的事情

using (SqlConnection conn = new SqlConnection(connectionString)) 
{ 
    conn.Open(); 
    conn.Execute(@"INSERT INTO TableName (param1, param2, param3) 
        VALUES (@param1, @param2, @param3)", records); 
} 
+0

Dapper是一個很好的圖書館,它認爲這對我的項目有點矯枉過正。感謝您的回答,如果我有更大/更多的db涉及項目,我會考慮Dapper。 – catlovespurple

+0

這取決於你。我使用了直接的ADO網絡方法數千次,所以我想我理解你的立場。但是從我的觀點來看,編寫所有這些東西對於很少的項目來說尤其是浪費時間 – Steve

-1

See this answer

但是,如果你想更新你的,然後做這個

public void InsertDataToDb() 
{ 
    string connectionString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString; 
    var records = GetRecords(); 

    using (SqlConnection conn = new SqlConnection(connectionString)) 
    { 
     StringBuilder nonQuery = new StringBuilder(); 
     foreach(var item in records) 
     { 
      nonQuery.AppendFormat("INSERT INTO TableName (param1, param2, param3) VALUES ({0}, {1}, {2});", 
       item.param1, 
       item.param2, 
       item.param3); 
     } 

     SqlCommand cmd = new SqlCommand(nonQuery.ToString()); 

     cmd.CommandType = CommandType.Text; 

     cmd.Connection = conn; 

     conn.Open(); 

     cmd.ExecuteNonQuery(); 

     cmd.Parameters.Clear(); 

     conn.Close(); 
    } 
} 
+0

使查詢未參數化並不是一個好的解決方案。您正在引入安全漏洞,現在需要處理諸如正確格式化日期和在文本中引用引號等內容。正確的方法是使用相同的概念,但使用參數(請參閱[Hambone's answer](http://stackoverflow.com/a/33355911/80274)) –

+0

...如何?它解決了他所問的問題嗎?你是否說這是因爲sql注入的安全性? ......當我寫我的同時,我提出了Hambone的回答。 – bdparrish

+0

怎麼樣?我指出了3個問題,爲什麼這不是一個好的解決方案。 –