2017-10-04 718 views
0

我有一個DataSet在C#與DataTables和PostgreSQL數據庫與相同的表。我在我的代碼中填入DataTable,並且想要INSERT DataTable到Postgresql DataBase。我試圖用簡單的SQL查詢插入它(INSERT INTO...),但是如果我有幾百行數百行的表,它會非常緩慢。我想,使用DataAdapter會提高性能,但我不明白,它是如何工作的。你能舉兩個例子解釋我嗎?如何通過Npgsql從C#DataSet填充PostgreSQL表?

案例1: 插入DataSet的表爲DataAdapter的PostgreSQL的

案例2: 插入從數據集只uniq的值到PostgreSQL(如果表中的數據庫與uniq的按鍵行和DataTable包含相同)

或者也許你可以建議閱讀什麼來學習DataAdapter ...無論如何,謝謝。

回答

0

除了普通的小數據集,你將很難打敗NpgSql的實現copy的性能,這可以通過你的NpgSqlConnection對象的BeginTextImport方法來實現。

因此,無論您的數據如何在應用程序中存在,如果通過文本導入(複製)轉儲輸出,它應該非常快速。這裏是一個如何使用數據表來實現的例子。記住數據表中的列和表中的列將不得不排隊 - 如果沒有,你需要管理這種或那種方式。

這假定NpgSql 3.1.9或更高版本。

object[] outRow = new object[dt.Columns.Count]; 

using (var writer = conn.BeginTextImport("copy <table> from STDIN WITH NULL AS '' CSV")) 
{ 
    foreach (DataRow rw in dt.Rows) 
    { 
     for (int col = 0; col < dt.Columns.Count; col++) 
      outRow[col] = rw[col]; 

     writer.WriteLine(string.Join(",", outRow)); 
    } 
} 

只要重複...哇,這真的取決於。定義「重複」。如果它只是一個「選擇不同」,那麼它也取決於您期望的重複數量。如果數量很少,那麼List.Exists<>可能就足夠了,但是如果你有大量的模型,Dictionary對象會使每個查找效率更高。一個典型的列表查找是O(n),而一個字典查找將是O(1)。

這裏有一本字典不同的插入了上面的例子中的一個漂亮的蠻力例如:

object[] outRow = new object[dt.Columns.Count]; 
Dictionary<string, bool> already = new Dictionary<string, bool>(); 
bool test; 

using (var writer = conn.BeginTextImport("copy <table> from STDIN WITH NULL AS '' CSV")) 
{ 
    foreach (DataRow rw in dt.Rows) 
    { 
     for (int col = 0; col < dt.Columns.Count; col++) 
      outRow[col] = rw[col]; 

     string output = string.Join(",", outRow); 
     if (!already.TryGetValue(output, out test)) 
     { 
      writer.WriteLine(output); 
      already.Add(output, true); 
     } 
    } 
} 

免責聲明:這是一個內存豬。如果您可以通過其他方式管理欺騙,或者保證數據的順序,還有其他許多選項。

如果你不能(或不願)使用批量複製插入,東西,這將有助於表現會來包裝你插入到一個事務(NpgSqlTransaction),但對於行幾十萬,我可以」你明白你爲什麼會這麼做。

+0

感謝您的回答!我認爲,副本是最好的方法。但是,爲什麼使用textcopy?可能使用二進制導入是更好的選擇?哪一個更快? –

+0

是的,二進制是高性能,但它也不是那麼簡單(在我看來)。您可能會驚訝於文本導入的速度。嘗試一下,讓我知道。 – Hambone