【ArcGIS Pro二次开发】(30):数据定义语言DDL详解

在之前的文章【ArcGIS Pro二次开发】(19):创建要素类(FeatureClass)中有涉及DDL的知识点,随着深入的学习,在这里做一个小总结。


一、DDL基本概念

ArcGIS Pro二次开发中的DDL API是一种【数据定义语言】,主要是用于创建、删除、编辑地理数据库以及地理数据库的部件(item),如要素类(FeatureClass)、表(Table)等。

1、Description类

DDL中有一个很重要的类:Description类,即描述类。主要用于指定要创建、修改或删除的数据库存对象。例如,【TableDescription】用来描述一个表。【TableDescription】有多个属性,其中一个属性【FieldDescriptin】则是用来描述字段的构成。

下面是一个【FieldDescriptin】的基本结构,其中【"InspectionDate"】是字段名, 【FieldType.Date】是字段类型,通俗的说,这两个属性相当于字段的主属性,是必须要有的属性,而后面属性列表中的【AliasName】是别名,相当于非必要属性,如果不定义的话,会采用默认值:

FieldDescription inspectionDateFieldDescription = new FieldDescription("InspectionDate", FieldType.Date)
{
  AliasName = "Inspection Date"
};

2、SchemaBuilder对象

SchemaBuilder对象(方案构建器?好难翻译),是在地理数据库内部构建的一个对象,用于DDL操作。可以将DDL操作加入SchemaBuilder对象中,按照一定的逻辑顺序执行操作。

例如:先创建SchemaBuilder对象:

SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);

再将表的创建添加到我们的DDL任务列表中:

schemaBuilder.Create(tableDescription);

注意这里可以添加多个任务到任务列表中。

然后,通过调用 Build方法来执行这组DDL操作。结果可以返回一个bool值,显示是否执行成功。

bool success = schemaBuilder.Build();

以下是官方文档中记录的SchemaBuilder对象的所有成员和方法:


二、要素类(FeatureClass)、表(Table)的操作

1、创建FeatureClass、Table

以创建Table首先,创建一系列字段描述对象【FieldDescriptin】。

一个【FieldDescriptin】描述一个字段,一个FeatureClass或Table通常有多个字段,所以我们需要的是多个【FieldDescriptin】的列表。

创建字段可以从头创建,也可以基于已有字段,示例如下:

// 从头创建一个字段描述
FieldDescription inspectionDateFieldDescription = new FieldDescription("InspectionDate", FieldType.Date)
{
  AliasName = "Inspection Date"
};

// 从已有的字段创建一个域字段描述
FieldDescription inspectionResultsFieldDescription = FieldDescription.CreateDomainField("InspectionResults", new CodedValueDomainDescription(inspectionResultsDomain));
inspectionResultsFieldDescription.AliasName = "Inspection Results";

创建所需的字段描述对象集后,下一步是创建一个定义表本身的表描述对象【TableDescription】。

【TableDescription】用于传递给【SchemaBuilder.Create】,通过【SchemaBuilder.Create】实现创建表的功能。

具体流程如下:

// 收集所有字段描述的列表
List<FieldDescription> fieldDescriptions = new List<FieldDescription>() 
  { globalIDFieldDescription, objectIDFieldDescription, inspectionDateFieldDescription, inspectionResultsFieldDescription, inspectionNotesFieldDescription };

// 创建一个【tableDescription】对象来描述要创建的表
TableDescription tableDescription = new TableDescription("PoleInspection", fieldDescriptions);

// 创建一个【SchemaBuilder】对象
SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);

// 将创建任务添加到DDL任务列表中
schemaBuilder.Create(tableDescription);

// 执行DDL
bool success = schemaBuilder.Build();

需要注意的是,上面的流程并没有添加ObjectID字段,执行结果,会自动添加ObjectID字段。

创建FeatureClass遵循与创建Table大致相同的原则。不过需要注意的是,你需要额外创建一个 【ShapeDescription】对象来定义shape字段。

【ShapeDescription】对象可以从一组特性创建,也可以使用现有要素类的【FeatureClassDefinition】创建。在这种情况下,新要素类将继承现有类的相同形状特性。

// 创建一个【ShapeDescription】对象
ShapeDescription shapeDescription = new ShapeDescription(GeometryType.Point, spatialReference);

// 或者,可以从另一个要素类创建【ShapeDescription】
ShapeDescription alternativeShapeDescription = new ShapeDescription(existingFeatureClass.GetDefinition());

最后一步则是创建【FeatureClassDescription】,并使用上面描述的相同模式构建要素类。具体如下:

// 创建一个【FeatureClassDescription】对象来描述要创建的要素类
FeatureClassDescription featureClassDescription = new FeatureClassDescription("Cities", fieldDescriptions, shapeDescription);

// 创建一个【SchemaBuilder】对象
SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);

// 将创建任务添加到DDL任务列表中
schemaBuilder.Create(featureClassDescription);

// 执行DDL
bool success = schemaBuilder.Build();

2、修改FeatureClass、Table

以给FeatureClass添加2个新字段为例。

首先,创建一个新的【FeatureClassDescription】。Name属性和【ShapeDescription】就用原有要素的,【FieldDescription】则是在继承原有的基础上,添加2个新字段,然后再替换掉原来的【FieldDescription】进行更新。具体代码如下:

// 要修改的要素
string featureClassName = "Parcels";

// 获取待修改要素的【FeatureClassDefinition】
FeatureClassDefinition originalFeatureClassDefinition = geodatabase.GetDefinition<FeatureClassDefinition>(featureClassName);
// 获取【FeatureClassDescription】
FeatureClassDescription originalFeatureClassDescription = new FeatureClassDescription(originalFeatureClassDefinition);

// 定义需要添加的2个字段
FieldDescription taxCodeDescription = FieldDescription.CreateIntegerField("Tax_Code");
FieldDescription addressDescription = FieldDescription.CreateStringField("Parcel_Address", 150);

// 将2个新字段添加到【FieldDescription】列表中
List<FieldDescription> modifiedFieldDescriptions = new List<FieldDescription>(originalFeatureClassDescription.FieldDescriptions);
modifiedFieldDescriptions.Add(taxCodeDescription);
modifiedFieldDescriptions.Add(addressDescription);

// 使用新添加的字段创建一个【FeatureClassDescription】
FeatureClassDescription modifiedFeatureClassDescription = new FeatureClassDescription(originalFeatureClassDescription.Name, modifiedFieldDescriptions, originalFeatureClassDescription.ShapeDescription);

SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);

// 更新【Parcels】要素
schemaBuilder.Modify(modifiedFeatureClassDescription);
bool modifyStatus = schemaBuilder.Build();
// 如果出现错误,返回
if (!modifyStatus)
{
  IReadOnlyList<string> errors = schemaBuilder.ErrorMessages;
}

3、重命名FeatureClass、Table

重命名表格或要素类,请创建与要重命名的表格或要素类匹配的【Description】对象。然后在【SchemaBuilder】类上调用Rename方法,代码如下:

// 定义原Name和要重命名的Name
string tableToBeRenamed = "Original_Table";
string tableRenameAs = "Renamed_Table";
// 获取要重命名的表的【TableDefinition】
TableDefinition tableDefinition = geodatabase.GetDefinition<TableDefinition>(tableToBeRenamed);

SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);

// 调用Rename方法即可重命名
schemaBuilder.Rename(new TableDescription(tableDefinition), tableRenameAs);
// 执行DDL
schemaBuilder.Build();

4、添加和删除字段

这里添加字段的方法和上面第2节使用的方法大致相同。

// 从现有表中获取【TableDescription】
TableDescription tableDescription = new TableDescription(parcelTableDefinition);

// 获取【FieldDescriptions】
List<FieldDescription> fieldDescriptions = new List<FieldDescription> (tableDescription.FieldDescriptions);

// 往【FieldDescriptions】中添加字段
fieldDescriptions.Add(FieldDescription.CreateIntegerField("FloodRiskScale"));

// 修改【TableDescription】
TableDescription modifiedTableDescription = new TableDescription(tableDescription.Name, fieldDescriptions);

// 更新【TableDescription】  
schemaBuilder.Modify(modifiedTableDescription);

// 执行DDL
schemaBuilder.Build();

删除字段方法如下:

// 从现有表中获取【TableDescription】
TableDescription tableDescription = new TableDescription(parcelTableDefinition);

// 定义要保留的字段
FieldDescription taxFieldToBeRetained = new FieldDescription(parcelTableDefinition.GetFields().First(f => f.Name.Equals("TaxCode")));
List<FieldDescription> fieldsToBeRetained = new List<FieldDescription> { taxFieldToBeRetained };

// 修改【TableDescription】
TableDescription modifiedTableDescription = new TableDescription(tableDescription.Name, fieldsToBeRetained);

// 更新【TableDescription】
schemaBuilder.Modify(modifiedTableDescription);

// 执行DDL
schemaBuilder.Build();

5、修改现有字段的属性

可以使用SchemaBuilder.Modify(TableDescription、String、FieldDescription)方法修改表或要素类中某些现有字段的字段属性,如名称、别名、长度和类型。

但是需要注意,有些固有字段是不能修改的,如ObjestID,Shape_Area等。

还有就是别名的最大长度为255个字符,地理数据库中不允许使用空字符串作为别名。

示例代码如下:

// 获取要修改的字段【Parcel_Address】
Field parcelAddress = featureClassDefinition.GetFields().FirstOrDefault(f => f.Name.Contains("Parcel_Address"));

// 更新字段的别名和长度
FieldDescription newParcelFieldDescription = new FieldDescription(parcelAddress) 
{
  AliasName = "Physical Property Address",
  Length = 250
};

// 设置默认的字段值
newParcelFieldDescription.SetDefaultValue("123 Main St");

schemaBuilder.Modify(new TableDescription(featureClassDefinition), parcelAddress.Name, newParcelFieldDescription);
schemaBuilder.Build();

6、删除FeatureClass、Table

要删除FeatureClass、Table只需要使用【SchemaBuilder.Delete】方法即可,其它的步骤和上面都差不多。

// 获取【tableDescription】
TableDescription tableDescription = new TableDescription(table.GetDefinition());

// 创建【SchemaBuilder】对象
SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);

// 调用【Delete】方法
schemaBuilder.Delete(tableDescription);

// // 执行DDL
bool success = schemaBuilder.Build();

三、文件地理数据库(GDB)的操作

1、创建和删除文件地理数据库

创建和删除文件地理数据库遵循的模式与其他DDL操作略有不同。可以调用【SchemaBuilder】类上的【CreateGeodatabase】和【DeleteGeodatabase】方法来创建和删除文件地理数据库。

这两个方法都以【FileGeodatabaseConnectionPath】作为参数,即文件路径。

需要注意的是,如果文件地理数据库正在使用中,则无法将其删除。所有对文件地理数据库的执行工作都必须在删除前完成。

// 创建【SchemaBuilder】对象
SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);

// 调用【CreateGeodatabase】方法创建数据库
schemaBuilder.CreateGeodatabase(GeodatabasePath);

// 执行DDL
bool success = schemaBuilder.Build();
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

规划GIS会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值