通过对 DBMS 中的表和视图定义查询,ArcMap 用户可将“查询图层”添加到地图。
查询图层类似于任何其他要素图层或单独表,所以这些图层可用于作为地理处理工具的输入来
显示数据,或使用开发人员 API 通过编程方式进行访问。
创建“查询图层”后,它可另存为图层文件 (.lyr) 或用于创建图层包 (.lpk)。这样可以很容易
地与其他应用程序、地图文档和其他用户共享“查询图层”。
ArcMap 中的所有图层都需要唯一标识符。因此,查询图层也必须含有唯一标识符。
通常,唯一标识符字段属于 ObjectID 属性,地理数据库中所有对象均应具有该属性。但是,由于
查询图层也可以使用未存储在地理数据库中的数据创建,因此各查询图层的字段集中未必都具有
ObjectID 字段。因此,有必要指定将哪个字段或哪组字段用于在 ArcGIS 中生成唯一标识符。
默认情况下,ArcGIS 会在验证时将在结果集中找到的第一个非空字段设置为唯一标识符字段。该值通常为
适宜用作唯一标识符字段的值,但您也可以通过在唯一标识符字段列表中选择其他字段来更改此属性。
仅某些字段类型可用作唯一标识符。这些字段类型包括整型、字符串、GUID 和日期。如果指定的是单个整
型字段,则 ArcGIS 将只会直接使用该字段中的值识别从查询图层返回的所有要素和行。但是,如果将单
个字符串字段或一组字段用作唯一标识符,则 ArcGIS 必须将这些唯一值映射为一个整数。在系统需要使
用 ObjectID 属性的任何时候(例如,创建地图选择内容或打开属性表时)均可在 ArcGIS 中完成此操作。
由于唯一标识符字段中的值是识别 ArcGIS 中行或要素对象的唯一值,因此,该字段中的值必须始终唯一
且不可为空。您必须确保此字段中的值满足此要求。ArcGIS 并不强制要求查询图层的唯一标识符字段中的
值必须唯一。但如果遇到不唯一的值,ArcGIS 中某些元素的行为将无法预测。
您可以在唯一标识符列表中选择和取消选择字段。如果选择了多个字段,则这些字段中的值将作为键用于
生成唯一整数值,生成字段的名称将始终为 ESRI_OID,除非已存在具有该名称的字段
在ArcGIS Engine中要使用查询图层,我们要了解一个接口ISqlWorkspace,从这个接口的名称也容易看
出,这个接口可以和SQL打交道,这正是QueryLayer的一个特点。在帮助文件中我们可以获得ISqlWorkspac
的详细信息,
ISqlWorkspace.GetTables()返回IStringArray类型的变量,用这个方法我们可以获取数
据库中所有的表的名称。
ISqlWorkspace.OpenQueryCursor()这个方法通过传入一个过滤语句,返回一个游标;
ISqlWorkspace.OpenQueryClass()返回通过过滤条件返回ITable类型的对象。
ISqlWorkspace被SqlWorkspaceClass实现,而SqlWorkspaceClass同时实现了IWorkspace
接口。那也就意味着ISqlWorkspace的使用和IWorksapce的使用是类似的,我们可以按照
以下步骤来执行一个QueryLayer。
1) 获取SqlWorkspaceFactory
2) 获取SqlWorkspace
3) 构造查询语句
4) 执行查询
5) 获取结果
public IFeatureLayer OracleQueryLayer()
{
// 创建SqlWorkspaceFactory的对象
Type pFactoryType =
Type.GetTypeFromProgID("esriDataSourcesGDB.SqlWorkspaceFactory");
IWorkspaceFactory pWorkspaceFactory =
(IWorkspaceFactory)Activator.CreateInstance(pFactoryType);
// 构造连接数据库的参数
IPropertySet pConnectionProps = new PropertySetClass();
pConnectionProps.SetProperty("dbclient", "Oracle11g");
pConnectionProps.SetProperty("serverinstance", "esri");
pConnectionProps.SetProperty("authentication_mode", "DBMS");
pConnectionProps.SetProperty("user", "scott");
pConnectionProps.SetProperty("password", "arcgis");
// 打开工作空间
IWorkspace workspace = pWorkspaceFactory.Open(pConnectionProps, 0);
ISqlWorkspace pSQLWorkspace = workspace as ISqlWorkspace;
//获取数据库中的所有表的名称
IStringArray pStringArray= pSQLWorkspace.GetTables();
for (int i = 0; i < pStringArray.Count; i++)
{
MessageBox.Show(pStringArray.get_Element(i));
}
// 构造过滤条件 SELECT * FROM PointQueryLayer
IQueryDescription queryDescription = pSQLWorkspace.GetQueryDescription("SELECT *
FROM PointQueryLayer");
ITable pTable = pSQLWorkspace.OpenQueryClass("QueryLayerTest", queryDescription);
IFeatureLayer pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.FeatureClass = pTable as IFeatureClass;
return pFeatureLayer;
}