大量のC#のdatatableをpostgresqlのテーブル

bulkinsert c# datatable postgresql sqlbulkcopy

質問

私は何千ものレコードを持つデータテーブルを持っています。私はデータテーブルの同じフィールドを持つpostgresテーブルを持っています。私は毎日このテーブルを切り捨てて、データテーブルのデータをもう一度埋めたいと思っています。私はSQLの一括コピーを見てきましたが、postgresでavalaibleではありません。それで、どちらが最も効果的な方法ですか?

  • レコードごとに1つの挿入
  • 複数の挿入:テーブル値(1,1)、(1,2)、(1,3)、(2,1)に挿入します。
  • データテーブルから選択し、linqでポストグアに挿入しますか?考えていない...

ありがとう。

エキスパート回答

PostgreSQLに一括挿入するオプションがあります。

たとえば、私のライブラリでは、私はSQLコピーを使用しています

COPY TableName (Column1, Column2, Column3) FROM STDIN BINARY

免責事項 :私はプロジェクトBulk-Operations.NETのオーナーです。

このライブラリを使用すると、あらゆる種類のバルク操作を非常に簡単に実行できます。

  • BulkInsert
  • 一括更新
  • BulkDelete
  • バルクマージ

PostgreSQLを含む複数のデータベースプロバイダ

// Easy to use
var bulk = new BulkOperation(connection);
bulk.BulkInsert(dt);
bulk.BulkUpdate(dt);
bulk.BulkDelete(dt);
bulk.BulkMerge(dt);

人気のある回答

おそらく、あなたは私がこの問題のために作成した小さなヘルパーを記述して、別のヘルパーを本当に簡単に使うことができるという私の他の答えをチェックすることができます: https : //stackoverflow.com/a/46063313/6654362

編集:私は最近、同様の問題に遭遇しましたが、PostgreSQLを使用していました。私は効果的なバルク挿入を使いたいと思っていましたが、かなり困難でした。私はこのDBでそうするための適切な無料のライブラリを発見していません。私はこのヘルパーを見つけただけです: https ://bytefish.de/blog/postgresql_bulk_insert/またNugetにあります。私はエンティティフレームワークと同じようにプロパティを自動マップする小さなマッパーを作成しました:

public static PostgreSQLCopyHelper<T> CreateHelper<T>(string schemaName, string tableName)
        {
            var helper = new PostgreSQLCopyHelper<T>(schemaName, "\"" + tableName + "\"");
            var properties = typeof(T).GetProperties();
            foreach(var prop in properties)
            {
                var type = prop.PropertyType;
                if (Attribute.IsDefined(prop, typeof(KeyAttribute)))
                    continue;
                switch (type)
                {
                    case Type intType when intType == typeof(int) || intType == typeof(int?):
                        {
                            helper = helper.MapInteger("\"" + prop.Name + "\"",  x => (int?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
                            break;
                        }
                    case Type stringType when stringType == typeof(string):
                        {
                            helper = helper.MapText("\"" + prop.Name + "\"", x => (string)typeof(T).GetProperty(prop.Name).GetValue(x, null));
                            break;
                        }
                    case Type dateType when dateType == typeof(DateTime) || dateType == typeof(DateTime?):
                        {
                            helper = helper.MapTimeStamp("\"" + prop.Name + "\"", x => (DateTime?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
                            break;
                        }
                    case Type decimalType when decimalType == typeof(decimal) || decimalType == typeof(decimal?):
                        {
                            helper = helper.MapMoney("\"" + prop.Name + "\"", x => (decimal?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
                            break;
                        }
                    case Type doubleType when doubleType == typeof(double) || doubleType == typeof(double?):
                        {
                            helper = helper.MapDouble("\"" + prop.Name + "\"", x => (double?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
                            break;
                        }
                    case Type floatType when floatType == typeof(float) || floatType == typeof(float?):
                        {
                            helper = helper.MapReal("\"" + prop.Name + "\"", x => (float?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
                            break;
                        }
                    case Type guidType when guidType == typeof(Guid):
                        {
                            helper = helper.MapUUID("\"" + prop.Name + "\"", x => (Guid)typeof(T).GetProperty(prop.Name).GetValue(x, null));
                            break;
                        }
                }
            }
            return helper;
        }

私はそれを以下の方法で使用します(私は事業体という事業体を持っていました)。

var undertakingHelper = BulkMapper.CreateHelper<Model.Undertaking>("dbo", nameof(Model.Undertaking));
undertakingHelper.SaveAll(transaction.UnderlyingTransaction.Connection as Npgsql.NpgsqlConnection, undertakingsToAdd));

トランザクションの例を示しましたが、コンテキストから取得した通常の接続でも実行できます。 undertakingsToAddは通常のエンティティレコードを列挙できます。これはDBにbulkInsertしたいものです。

数時間の研究と試行後に得られたこのソリューションは、はるかに高速で、最終的には使いやすく、無料で使えると期待されています。上記の理由だけでなく、PostgreSQL自体に問題がなかった唯一の理由でもありますので、他の多くのソリューションがSqlServerなどで完璧に動作します。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ