2017-10-04 716 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