• 【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】是别名,相当于非必要属性,如果不定义的话,会采用默认值:

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

    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】的列表。

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

    1. // 从头创建一个字段描述
    2. FieldDescription inspectionDateFieldDescription = new FieldDescription("InspectionDate", FieldType.Date)
    3. {
    4. AliasName = "Inspection Date"
    5. };
    6. // 从已有的字段创建一个域字段描述
    7. FieldDescription inspectionResultsFieldDescription = FieldDescription.CreateDomainField("InspectionResults", new CodedValueDomainDescription(inspectionResultsDomain));
    8. inspectionResultsFieldDescription.AliasName = "Inspection Results";

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

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

    具体流程如下:

    1. // 收集所有字段描述的列表
    2. List fieldDescriptions = new List()
    3. { globalIDFieldDescription, objectIDFieldDescription, inspectionDateFieldDescription, inspectionResultsFieldDescription, inspectionNotesFieldDescription };
    4. // 创建一个【tableDescription】对象来描述要创建的表
    5. TableDescription tableDescription = new TableDescription("PoleInspection", fieldDescriptions);
    6. // 创建一个【SchemaBuilder】对象
    7. SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);
    8. // 将创建任务添加到DDL任务列表中
    9. schemaBuilder.Create(tableDescription);
    10. // 执行DDL
    11. bool success = schemaBuilder.Build();

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

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

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

    1. // 创建一个【ShapeDescription】对象
    2. ShapeDescription shapeDescription = new ShapeDescription(GeometryType.Point, spatialReference);
    3. // 或者,可以从另一个要素类创建【ShapeDescription】
    4. ShapeDescription alternativeShapeDescription = new ShapeDescription(existingFeatureClass.GetDefinition());

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

    1. // 创建一个【FeatureClassDescription】对象来描述要创建的要素类
    2. FeatureClassDescription featureClassDescription = new FeatureClassDescription("Cities", fieldDescriptions, shapeDescription);
    3. // 创建一个【SchemaBuilder】对象
    4. SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);
    5. // 将创建任务添加到DDL任务列表中
    6. schemaBuilder.Create(featureClassDescription);
    7. // 执行DDL
    8. bool success = schemaBuilder.Build();

    2、修改FeatureClass、Table

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

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

    1. // 要修改的要素
    2. string featureClassName = "Parcels";
    3. // 获取待修改要素的【FeatureClassDefinition】
    4. FeatureClassDefinition originalFeatureClassDefinition = geodatabase.GetDefinition(featureClassName);
    5. // 获取【FeatureClassDescription】
    6. FeatureClassDescription originalFeatureClassDescription = new FeatureClassDescription(originalFeatureClassDefinition);
    7. // 定义需要添加的2个字段
    8. FieldDescription taxCodeDescription = FieldDescription.CreateIntegerField("Tax_Code");
    9. FieldDescription addressDescription = FieldDescription.CreateStringField("Parcel_Address", 150);
    10. // 将2个新字段添加到【FieldDescription】列表中
    11. List modifiedFieldDescriptions = new List(originalFeatureClassDescription.FieldDescriptions);
    12. modifiedFieldDescriptions.Add(taxCodeDescription);
    13. modifiedFieldDescriptions.Add(addressDescription);
    14. // 使用新添加的字段创建一个【FeatureClassDescription】
    15. FeatureClassDescription modifiedFeatureClassDescription = new FeatureClassDescription(originalFeatureClassDescription.Name, modifiedFieldDescriptions, originalFeatureClassDescription.ShapeDescription);
    16. SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);
    17. // 更新【Parcels】要素
    18. schemaBuilder.Modify(modifiedFeatureClassDescription);
    19. bool modifyStatus = schemaBuilder.Build();
    20. // 如果出现错误,返回
    21. if (!modifyStatus)
    22. {
    23. IReadOnlyList<string> errors = schemaBuilder.ErrorMessages;
    24. }

    3、重命名FeatureClass、Table

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

    1. // 定义原Name和要重命名的Name
    2. string tableToBeRenamed = "Original_Table";
    3. string tableRenameAs = "Renamed_Table";
    4. // 获取要重命名的表的【TableDefinition】
    5. TableDefinition tableDefinition = geodatabase.GetDefinition(tableToBeRenamed);
    6. SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);
    7. // 调用Rename方法即可重命名
    8. schemaBuilder.Rename(new TableDescription(tableDefinition), tableRenameAs);
    9. // 执行DDL
    10. schemaBuilder.Build();

    4、添加和删除字段

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

    1. // 从现有表中获取【TableDescription】
    2. TableDescription tableDescription = new TableDescription(parcelTableDefinition);
    3. // 获取【FieldDescriptions】
    4. List fieldDescriptions = new List (tableDescription.FieldDescriptions);
    5. // 往【FieldDescriptions】中添加字段
    6. fieldDescriptions.Add(FieldDescription.CreateIntegerField("FloodRiskScale"));
    7. // 修改【TableDescription】
    8. TableDescription modifiedTableDescription = new TableDescription(tableDescription.Name, fieldDescriptions);
    9. // 更新【TableDescription】
    10. schemaBuilder.Modify(modifiedTableDescription);
    11. // 执行DDL
    12. schemaBuilder.Build();

    删除字段方法如下:

    1. // 从现有表中获取【TableDescription】
    2. TableDescription tableDescription = new TableDescription(parcelTableDefinition);
    3. // 定义要保留的字段
    4. FieldDescription taxFieldToBeRetained = new FieldDescription(parcelTableDefinition.GetFields().First(f => f.Name.Equals("TaxCode")));
    5. List fieldsToBeRetained = new List { taxFieldToBeRetained };
    6. // 修改【TableDescription】
    7. TableDescription modifiedTableDescription = new TableDescription(tableDescription.Name, fieldsToBeRetained);
    8. // 更新【TableDescription】
    9. schemaBuilder.Modify(modifiedTableDescription);
    10. // 执行DDL
    11. schemaBuilder.Build();

    5、修改现有字段的属性

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

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

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

    示例代码如下:

    1. // 获取要修改的字段【Parcel_Address】
    2. Field parcelAddress = featureClassDefinition.GetFields().FirstOrDefault(f => f.Name.Contains("Parcel_Address"));
    3. // 更新字段的别名和长度
    4. FieldDescription newParcelFieldDescription = new FieldDescription(parcelAddress)
    5. {
    6. AliasName = "Physical Property Address",
    7. Length = 250
    8. };
    9. // 设置默认的字段值
    10. newParcelFieldDescription.SetDefaultValue("123 Main St");
    11. schemaBuilder.Modify(new TableDescription(featureClassDefinition), parcelAddress.Name, newParcelFieldDescription);
    12. schemaBuilder.Build();

    6、删除FeatureClass、Table

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

    1. // 获取【tableDescription】
    2. TableDescription tableDescription = new TableDescription(table.GetDefinition());
    3. // 创建【SchemaBuilder】对象
    4. SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);
    5. // 调用【Delete】方法
    6. schemaBuilder.Delete(tableDescription);
    7. // // 执行DDL
    8. bool success = schemaBuilder.Build();

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

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

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

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

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

    1. // 创建【SchemaBuilder】对象
    2. SchemaBuilder schemaBuilder = new SchemaBuilder(geodatabase);
    3. // 调用【CreateGeodatabase】方法创建数据库
    4. schemaBuilder.CreateGeodatabase(GeodatabasePath);
    5. // 执行DDL
    6. bool success = schemaBuilder.Build();
  • 相关阅读:
    STM32CUBEMX_DMA串口空闲中断接收+接收发送缓冲区
    技术管理进阶——如何脱颖而出?
    Github每日精选(第66期):擦图老照片修复神器--Lama Cleaner
    Java开发学习(三十四)----Maven私服(二)本地仓库访问私服配置与私服资源上传下载
    初学AJAX:express框架基本使用、ajax处理get/post请求、请求超时与网络异常处理、取消请求操作
    「金三银四」这些面试题,看看你会答几道?
    【面经】被虐了之后,我翻烂了equals源码,总结如下
    2022软件测试技能 Jmeter+Ant+Jenkins持续集成并生成测试报告教程
    企业电子文档管理系统哪个好?怎么选?
    SSH协议简介与使用
  • 原文地址:https://blog.csdn.net/xcc34452366/article/details/130832302