文件数据导入数据库思路 - zLulus/My_Note GitHub Wiki

以.shp文件为例,.shp文件有20个字段,目标业务表有30个字段,直接使用ImportSettingSHP导入业务表,不成功
正确思路是:
(1)使用ImportSettingSHP将.shp数据导入一个临时数据集(比如.udb)

 private ImportResult ImportShpToTemp(string filePath, Datasource tempDatasource,string targetTableName)
{
	ImportSettingSHP importSettingSHP = new ImportSettingSHP();
	importSettingSHP.IsAttributeIgnored = false;
	importSettingSHP.IsImportAs3D = false;
	//设置当同名数据集存在时导入的模式,如果存在名字冲突,则覆盖(Overwrite)
	importSettingSHP.ImportMode = ImportMode.Overwrite;
	//设置需要导入的数据路径信息
	importSettingSHP.SourceFilePath = filePath;
	//设置需要导入的数据编码类型,因为有中文字段,所以用ASCII编码
	importSettingSHP.SourceFileCharset = Charset.ANSI;
	//设置要导入的目标数据源(udb数据源)
	importSettingSHP.TargetDatasource = tempDatasource;
	//设置目标数据集名称
	importSettingSHP.TargetDatasetName = targetTableName;
	importSettingSHP.TargetEncodeType = EncodeType.None;
	DataImport importer = new DataImport();
	importer.ImportSettings.Add(importSettingSHP);
	//数据导入mysql数据库
	ImportResult result = importer.Run();
	return result;
}

(2)创建数据库数据源,并且已经建立对应数据集(见超图自定义数据集名称
读取临时数据集,依次将几何对象、shp文件中的字段赋值给数据库数据源的记录集

//tempDatasource:临时数据集,datasource:数据库数据集
DatasetVector tempDatasetVector = (DatasetVector)tempDatasource.Datasets[0];
tempRecordset = tempDatasetVector.GetRecordset(false, SuperMap.Data.CursorType.Dynamic);
var tempFieldInfos = tempDatasetVector.FieldInfos;
//注意:数据集是手工录入的,不是超图sdk生成的,所以不能删除数据集
//如果更新数据集中的记录,则应该操纵记录集(删除、修改、新增)
var datasetVector = (DatasetVector)datasource.Datasets[tableName];
if (datasetVector == null)
{
	throw new Exception($"不存在数据集名称为{tableName}的数据集!");
}
//只取了数据结构,没有取数据
recordset = datasetVector.GetRecordset(true, CursorType.Dynamic);
//从第一条数据开始
tempRecordset.MoveFirst();
//遍历临时记录集
for (Int32 i = 0; i < tempRecordset.RecordCount; i++)
{
	//往数据库记录集新增记录
	Geometry geoPoint = tempRecordset.GetGeometry();
	recordset.AddNew(geoPoint);
	//到达刚刚新增的记录集
	recordset.MoveLast();
	foreach (SuperMap.Data.FieldInfo fileInfo in tempFieldInfos)
	{
	    //不是超图系统字段,并且数据库表中有该字段
		if (!fileInfo.IsSystemField && IsHaveField(datasetVector.FieldInfos, fileInfo.Name))
		{
			recordset.Edit();
			recordset.SetFieldValue(fileInfo.Name, tempRecordset.GetFieldValue(fileInfo.Name));
			//查看数据
			Object valueID = recordset.GetFieldValue(fileInfo.Name);
		}
	}

	//处理业务数据(不在shp文件中的字段)
	var ID = "ID";
	var IDVal = $"D{recordset.GetFieldValue("SmID")}";
	if(IsHaveField(recordset.GetFieldInfos(), ID))
	{
		recordset.SetFieldValue(ID, IDVal);
	}

	//提交数据
	recordset.Update();
	//到下一条数据
	tempRecordset.MoveNext();
}
//释放资源
recordset.Dispose();
tempRecordset.Dispose();

(3)给数据库数据源的其他字段(非shp文件字段)赋值

//处理业务数据(不在shp文件中的字段)
var ID = "ID";
var IDVal = $"D{recordset.GetFieldValue("SmID")}";
if(IsHaveField(recordset.GetFieldInfos(), ID))
{
	recordset.SetFieldValue(ID, IDVal);
}

(4)提交保存数据源

recordset.Update();

或者使用

//设置批量提交
// 设置批量更新的限度为5000,注意一定要在开始批量更新前设置MaxRecordCount!
recordset.Batch.MaxRecordCount = 500;
// 开始批量更新,当添加到设置的MaxRecordCount的下一条记录时,将会将MaxRecordCount条记录自动提交到数据库中。
recordset.Batch.Begin();
//...
// 使用批量更新的Update,提交没有自动提交的记录
recordset.Batch.Update();

注意事项

importSettingSHP.ImportMode = ImportMode.Overwrite;
importSettingSHP.ImportMode = ImportMode.None;
importSettingSHP.ImportMode = ImportMode.Append;

ImportMode.Overwrite会删除现有数据集,新建一个数据集(smregister删除数据集记录)
ImportMode.None和ImportMode.Append才是存入现有数据集