【问题标题】:How to fill PostgreSQL tables from C# DataSet via Npgsql?如何通过 Npgsql 从 C# DataSet 填充 PostgreSQL 表?
【发布时间】:2018-03-16 09:01:55
【问题描述】:

我在 C# 中有一个 DataSetDataTables 和具有相同表的 PostgreSQL 数据库。我在我的代码中填写DataTable 并希望将INSERT DataTable 写入Postgresql 数据库。我尝试使用简单的 SQL 查询 (INSERT INTO...) 插入它,但如果我有数百个数千行的表,它会非常慢。我想,使用 DataAdapter 会提高性能,但我不明白它是如何工作的。你能用两个例子解释一下吗?

案例1: 使用 DataAdapter 将 DataSet 的表插入 Postgresql

案例2: 仅将 uniq 值从 DataSet 插入到 PostgreSQL(如果数据库中的表具有具有 uniq 键的行并且 DataTable 包含相同的行)

或者,也许您可​​以建议阅读什么来学习 DataAdapters...无论如何,谢谢。

【问题讨论】:

    标签: c# postgresql npgsql dataadapter


    【解决方案1】:

    除了很小的数据集之外,您将很难超越 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&lt;&gt; 可能就足够了,但如果你有大量的欺骗,一个 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),但是对于数十万行,我可以'不明白你为什么会这样做。

    【讨论】:

    • 感谢您的回答!我认为,副本是最好的方式。但是,为什么是文本副本?可能使用二进制导入是更好的选择?哪个更快?
    • 是的,二进制是高性能的,但也没有那么简单(在我看来)。您可能会对文本导入的速度感到惊讶。试试看,让我知道。
    猜你喜欢
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 2011-09-09
    相关资源
    最近更新 更多