Npgsql使用入门(三)【批量导入数据】
Program.cs代码:
class Program
{
static void Main(string[] args)
{
var test = new PgBulkCopyHelper<SingleBuilding>("bld_amap_gzmain");
foreach (string pName in test.PropNames)
{
Console.WriteLine("name: {0},\t\ttype: {1}", pName, test.PropInfo[pName]);
}
//-----------------------------------------------------------------------------------------------
//定义每次插入的最大数量限制
int maxNum = 1; //100000;
//初始化对应的数据表
DataTable dataTable = test.InitDataTable();
string connectionString = "Host=localhost;Username=king;Password=wu12345;Database=dellstore";
List<List<SingleBuilding>> bldsList = new List<List<SingleBuilding>>();
NpgsqlPolygon plg1 = new NpgsqlPolygon(10);
plg1.Add(new NpgsqlPoint(0.0, 0.0));
plg1.Add(new NpgsqlPoint(6.0, -1.0));
plg1.Add(new NpgsqlPoint(5.0, 3.0));
plg1.Add(new NpgsqlPoint(1.0, 2.0));
NpgsqlPolygon plg2 = new NpgsqlPolygon(10);
plg2.Add(new NpgsqlPoint(100.0, 10.0));
plg2.Add(new NpgsqlPoint(40.0, 180.0));
plg2.Add(new NpgsqlPoint(190.0, 60.0));
plg2.Add(new NpgsqlPoint(10.0, 60.0));
plg2.Add(new NpgsqlPoint(160.0, 180.0));
List<SingleBuilding> sblist1 = new List<SingleBuilding>(){
new SingleBuilding(){id=System.Guid.NewGuid(),
tile_x=1,
tile_y=2,
bps_gc=plg1,
bps_llc=plg2,
cp_gc=new NpgsqlPoint(0,0),
cp_llc=new NpgsqlPoint(100,10),
name="测试文本1",
bld_floor=111,
height=22
},
new SingleBuilding(){id=System.Guid.NewGuid(),
tile_x=1,
tile_y=2,
bps_gc=plg1,
bps_llc=plg2,
cp_gc=new NpgsqlPoint(0,0),
cp_llc=new NpgsqlPoint(100,10),
name="测试文本2",
bld_floor=222,
height=444
}
};
bldsList.Add(sblist1);
using (var conn = new NpgsqlConnection(connectionString))
{
conn.Open();
foreach (List<SingleBuilding> blds in bldsList)
{
if (blds != null && blds.Count > 0)
{
//填充数据
test.FillDataTable(blds, dataTable);
}
//判断 dataTable 里面的数据量是否已经超过规定最大行数 maxNum
if (dataTable.Rows.Count>maxNum)
{
//如果是,则将 dataTable 里面的数据插入到数据库中
test.BulkInsert(conn, dataTable);
//清空 dataTable 中的现有数据
dataTable.Clear();
}
}
}
}
}
public class SingleBuilding
{
//创建数据表的SQL语句如下:
/*
CREATE TABLE bld_amap_gzmain (
id uuid PRIMARY KEY NOT NULL,
tile_x integer, --x index of the map tile where the building is located
tile_y integer, --y index of the map tile where the building is located
bps_gc polygon NOT NULL, --the points of the bottom outline of the building, geodetic coordinates
bps_llc polygon NOT NULL, --the points of the bottom outline of the building, Latitude and longitude coordinates
cp_gc point NOT NULL, --the center point of the building, geodetic coordinates
cp_llc point NOT NULL, --the center point of the building, Latitude and longitude coordinates
name text,
bld_floor smallint, --the number of floors of the building
height real --the height of building
);
*/
public Guid id { get; set; }
public int? tile_x { get; set; }
public int? tile_y { get; set; }
public NpgsqlPolygon bps_gc { get; set; }
public NpgsqlPolygon bps_llc { get; set; }
public NpgsqlPoint cp_gc { get; set; }
public NpgsqlPoint cp_llc { get; set; }
public string name { get; set; }
public short? bld_floor { get; set; }
public float? height { get; set; }
}
PgBulkCopyHelper.cs代码:
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace PgBulkCopyHelper
{
/// <summary>
/// 用以快速将大批量数据插入到postgresql中
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class PgBulkCopyHelper<TEntity>
{
/// <summary>
/// TEntity的属性信息
/// Dictionary(string "property_name", Type property_type)
/// </summary>
public Dictionary<string, Type> PropInfo { get; set; }
/// <summary>
/// TEntity的属性名称列表
/// </summary>
public List<string> PropNames { get; set; }
/// <summary>
/// 数据表全名:schema.tableName or tableName
/// </summary>
public string FullTableName { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="schema">数据表的schema,一般为public</param>
/// <param name="tableName">数据表的名称</param>
public PgBulkCopyHelper(string schema, string tableName)
{
PropNames = new List<string>();
PropInfo = new Dictionary<string, Type>();
PropertyInfo[] typeArgs = GetPropertyFromTEntity();
foreach (PropertyInfo tParam in typeArgs)
{
PropNames.Add(tParam.Name);
PropInfo[tParam.Name] = tParam.PropertyType;
}
if (!string.IsNullOrWhiteSpace(tableName))
{
if (string.IsNullOrWhiteSpace(schema))
{
FullTableName = tableName;
}
else
FullTableName = string.Format("{0}.{1}", schema, tableName);
}
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="tableName">数据表的名称</param>
public PgBulkCopyHelper(string tableName)
:this(null, tableName)
{ }
/// <summary>
/// 获取TEntity的属性信息
/// </summary>
/// <returns>TEntity的属性信息的列表</returns>
private PropertyInfo[] GetPropertyFromTEntity()
{
Type t = typeof(TEntity);
PropertyInfo[] typeArgs = t.GetProperties();
return typeArgs;
}
/// <summary>
/// 根据TEntity的属性信息构造对应数据表
/// </summary>
/// <returns>只有字段信息的数据表</returns>
public DataTable InitDataTable()
{
DataTable dataTable = new DataTable();
foreach(PropertyInfo tParam in GetPropertyFromTEntity())
{
Type propType = tParam.PropertyType;
//由于 DataSet 不支持 System.Nullable<> 类型,因此要先做判断
if ((propType.IsGenericType) && (propType.GetGenericTypeDefinition() == typeof(Nullable<>)))
propType = propType.GetGenericArguments()[0];
dataTable.Columns.Add(tParam.Name, propType);
}
return dataTable;
}
/// <summary>
/// 根据TEntity可枚举列表填充给定的数据表
/// </summary>
/// <param name="entities">TEntity类型的可枚举列表</param>
/// <param name="dataTable">数据表</param>
public void FillDataTable(IEnumerable<TEntity> entities, DataTable dataTable)
{
if (entities != null && entities.Count() > 0)
{
foreach (TEntity entity in entities)
{
FillDataTable(entity, dataTable);
}
}
}
/// <summary>
/// 在DataTable中插入单条数据
/// </summary>
/// <param name="entity">具体数据</param>
/// <param name="dataTable">数据表</param>
public void FillDataTable(TEntity entity, DataTable dataTable)
{
var dataRow = dataTable.NewRow();
int colNum = dataTable.Columns.Count;
PropertyInfo[] typeArgs = GetPropertyFromTEntity();
for (int i = 0; i < colNum; i++)
{
dataRow[i] = typeArgs[i].GetValue(entity);
}
dataTable.Rows.Add(dataRow);
}
/// <summary>
/// 通过PostgreSQL连接把dataTable中的数据整块填充到数据库对应的数据表中
/// 注意,该函数不负责NpgsqlConnection的创建、打开以及关闭
/// </summary>
/// <param name="conn">PostgreSQL连接</param>
/// <param name="dataTable">数据表</param>
public void BulkInsert(NpgsqlConnection conn, DataTable dataTable)
{
var commandFormat = string.Format(CultureInfo.InvariantCulture, "COPY {0} FROM STDIN BINARY", FullTableName);
using (var writer = conn.BeginBinaryImport(commandFormat))
{
foreach (DataRow item in dataTable.Rows)
writer.WriteRow(item.ItemArray);
}
}
}
}
运行结果如图:
Npgsql使用入门(三)【批量导入数据】的更多相关文章
- neo4j批量导入数据的两种解决方案
neo4j批量导入数据有两种方法,第一种是使用cypher语法中的LOAD CSV,第二种是使用neo4j自带的工具neo4j-admin import. LOAD CSV 导入的文件必须是csv文件 ...
- csv文件批量导入数据到sqlite。
csv文件批量导入数据到sqlite. 代码: f = web.input(bs_switch = {}) # bs_switch 为from表单file字段的namedata =[i.split( ...
- 使用python向Redis批量导入数据
1.使用pipeline进行批量导入数据.包含先使用rpush插入数据,然后使用expire改动过期时间 class Redis_Handler(Handler): def connect(self) ...
- Cassandra使用pycassa批量导入数据
本周接手了一个Cassandra系统的维护工作,有一项是需要将应用方的数据导入我们维护的Cassandra集群,并且为应用方提供HTTP的方式访问服务.这是我第一次接触KV系统,原来只是走马观花似的看 ...
- Redis批量导入数据的方法
有时候,我们需要给redis库中插入大量的数据,如做性能测试前的准备数据.遇到这种情况时,偶尔可能也会懵逼一下,这里就给大家介绍一个批量导入数据的方法. 先准备一个redis protocol的文件( ...
- 项目总结04:SQL批量导入数据:将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库
将具有多表关联的Excel数据,通过sql语句脚本的形式,导入到数据库 写在前面:本文用的语言是java:数据库是MySql: 需求:在实际项目中,经常会被客户要求,做批量导入数据:一般的简单的单表数 ...
- 批量导入数据到mssql数据库的
概述 批量导入数据到数据库中,我们有好几种方式. 从一个数据表里生成数据脚本,到另一个数据库里执行脚本 从EXCEL里导入数据 上面两种方式,导入的数据都会生成大量的日志.如果批量导入5W条数据到数据 ...
- asp.net线程批量导入数据时通过ajax获取执行状态
最近因为工作中遇到一个需求,需要做了一个批量导入功能,但长时间运行没个反馈状态,很容易让人看了心急,产生各种臆想!为了解决心里障碍,写了这么个功能. 通过线程执行导入,并把正在执行的状态存入sessi ...
- ADO.NET 对数据操作 以及如何通过C# 事务批量导入数据
ADO.NET 对数据操作 以及如何通过C# 事务批量导入数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...
- asp.net 线程批量导入数据,ajax获取执行状态
最近做了一个批量导入功能,长时间运行,没个反馈状态,很容易让人看了心急,产生各种臆想!为了解决心里障碍,写了这么个功能. 通过线程执行导入,并把正在执行的状态存入session,既共享执行状态,通过a ...
随机推荐
- ABP(http://www.aspnetboilerplate.com/)下载初始化
官网:http://www.aspnetboilerplate.com/ 下载 下载完成后用vs2015打开,是2015,低版本打开可能会出现一些问题 生成项目,Nuget会自动下载需要的类库 ABP ...
- C# 获得剪贴板内容和 richTextBox部分文本设置颜色
try { MemoryStream vMemoryStream = iData.GetData("Html Format") as MemoryStream; if (vMemo ...
- Keras手写识别例子(1)----softmax
转自:https://morvanzhou.github.io/tutorials/machine-learning/keras/2-2-classifier/#测试模型 下载数据: # downlo ...
- pause、jobs、setitimer(2)、system v ipc(day12)
一.pause()的使用 #include <unistd.h> int pause(void); 功能:等待信号的到来 返回值: - 错误 errno被设置 只有在信号处理函数执行完毕的 ...
- Codeforces 816A/B
A. Karen and Morning 传送门:http://codeforces.com/contest/816/problem/A 水题,参考程序如下: #include <stdio.h ...
- redis命令学习的注意问题
1.set get命令只用于字符串,get命令取key值时string正常返回,没有key返回nil,其他类型会报错 设置的时候是set test redis ex 200000等同于SETEX te ...
- BZOJ 1396 识别子串 (后缀自动机、线段树)
手动博客搬家: 本文发表于20181221 00:58:26, 原地址https://blog.csdn.net/suncongbo/article/details/85150962 嗯,以后博客内容 ...
- POJ 4046 Sightseeing
Sightseeing Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID ...
- oracle到mysql的导数据方式(适用于任意数据源之间的互导)
http://www.wfuyu.com/Internet/19955.html 为了生产库释放部份资源, 需要将API模块迁移到mysql中,及需要导数据. 尝试了oracle to mysql工具 ...
- POJ 3076
DLX算法,刚接触,是关于精确覆盖的,白书上有算法介绍. 代码模板 #include <iostream> #include <cstdio> #include <cst ...