How to use copy and paste to transfer data


Summary
The article shows how to use the IGeoDBDataTransfer interface to copy data between two geodatabases. Also shown is how to handle naming conflicts when they arise, as well as how to manually rename datasets during a copy and change configuration keywords of the datasets.

In this topic


Using copy and paste to transfer data

The IGeoDBDataTransfer interface is used to copy one or more datasets from one geodatabase to another geodatabase.  This includes tables, feature classes, feature datasets, or any other kind of dataset, as well as a set containing different types of datasets.
The IGeoDBDataTransfer interface is designed to work with an ArcCatalog IGxDialog mini-browser.  As this example does not use an ArcCatalog IGxDialog mini-browser, the following objects must first be created to be utilize this functionality:
First, create IWorkspaceName objects for the two workspaces: the source workspace (which holds the dataset(s) to be copied) and the target workspace.  The following example shows how to acquire a name object from a workspace:
[Java]
static IWorkspaceName getWorkspaceName(IWorkspace workspace)throws Exception{
    // Cast to the IDataset interface and get a Name object.
    IDataset dataset = (IDataset)workspace;
    IName name = dataset.getFullName();
    // Cast to the IWorkspaceName interface and return.
    IWorkspaceName workspaceName = (IWorkspaceName)name;
    return workspaceName;
}
A name object is also required for each dataset to be copied.  Create an instance of a name subclass based on the dataset's type, set its properties through the IDatasetName interface, and cast it to the IName interface. The following example shows how to do this; note that this example only works for feature datasets, feature classes, and tables, but this method could be expanded to take into account any additional datasets needed.  See the esriDatasetType enumeration for a complete list of dataset types.
[Java]
static IName getDatasetName(IDataset dataset, IWorkspaceName workspaceName)throws
    Exception{
    // Create a name object based on the dataset type.
    IDatasetName datasetName;
    switch (dataset.getType()){
        case esriDatasetType.esriDTFeatureDataset:
            IFeatureDatasetName inFeatureDatasetName = new FeatureDatasetName();
            datasetName = (IDatasetName)inFeatureDatasetName;
            break;
        case esriDatasetType.esriDTFeatureClass:
            IFeatureClassName inFeatureClassName = new FeatureClassName();
            datasetName = (IDatasetName)inFeatureClassName;
            break;
        case esriDatasetType.esriDTTable:
            ITableName inTableName = new TableName();
            datasetName = (IDatasetName)inTableName;
            break;
        case esriDatasetType.esriDTGeometricNetwork:
            IGeometricNetworkName inGeometricNetworkName = new GeometricNetworkName()
                ;
            datasetName = (IDatasetName)inGeometricNetworkName;
            break;
        case esriDatasetType.esriDTRelationshipClass:
            IRelationshipClassName inRelationshipClassName = new
                RelationshipClassName();
            datasetName = (IDatasetName)inRelationshipClassName;
            break;
        case esriDatasetType.esriDTNetworkDataset:
            INetworkDatasetName inNetworkDatasetName = new NetworkDatasetName();
            datasetName = (IDatasetName)inNetworkDatasetName;
            break;
        case esriDatasetType.esriDTTopology:
            ITopologyName inTopologyName = new TopologyName();
            datasetName = (IDatasetName)inTopologyName;
            break;
        default:
            return null;
    }

    // Set the name and workspace name of the new name object.
    datasetName.setName(dataset.getName());
    datasetName.setWorkspaceNameByRef(workspaceName);
    // Cast the object to the IName interface and return it.
    IName name = (IName)datasetName;
    return name;
}
An enumerator of name objects must be created for the dataset(s) to be copied.  See the following code example:
[Java]
static IEnumName getDatasetNameEnum(List < IName > nameList)throws Exception{
    // Create the enumerator and cast it to the IEnumNameEdit interface.
    IEnumName enumName = new NamesEnumerator();
    IEnumNameEdit enumNameEdit = (IEnumNameEdit)enumName;
    // Add the input name objects to the enumerator and return it.
    for (IName name: nameList){
        enumNameEdit.add(name);
    }
    return enumName;
}
Next, do the name mapping. If the IGeoDBDataTransfer.GenerateNameMapping method returns false, there are no name conflicts and you can proceed with the copy and paste. If it returns true, there are name conflicts that need to be handled (see Handling name conflicts for a description and the code for the ResolveNameConflicts method).  If object names need to be manually changed, or keywords need to be assigned, see Changing object names and keywords.
Following these steps, IGeoDBDataTransfer.Transfer can be called to copy the data, with the enumerator of name mappings and the target name as parameters. See the following code example:
[Java]
static void transferData(IEnumName enumSourceName, IName targetName)throws Exception{
    // Create the transfer object and a reference to a mapping enumerator.
    IGeoDBDataTransfer geoDBDataTransfer = new GeoDBDataTransfer();
    IEnumNameMapping[] enumNameMapping = new IEnumNameMapping[1];
    // See if the transfer can proceed with the datasets' existing names.
    Boolean targetObjectsExist = geoDBDataTransfer.generateNameMapping
        (enumSourceName, targetName, enumNameMapping);
    // See if any conflicts exist. 
    if (targetObjectsExist){
        // Handle this in a way appropriate to the application.
        // See the ResolveNameConflicts method described at:
        // http://edndoc.esri.com/arcobjects/9.2/NET/67a4021b-a15d-4fd4-8114-7128f3a1e9ce.htm#Handling
        resolveNameConflicts(enumNameMapping[0], targetName);
    }
    else{
        geoDBDataTransfer.transfer(enumNameMapping[0], targetName);
    }
}

Handling name conflicts

If the call to IGeoDBDataTransfer.GenerateNameMapping returns true, the mappings must be iterated through, checked for conflicts, and if found, have the name suggested by INameMapping.GetSuggestedName applied.
Since an INameMapping may have children, they also must be checked for conflicts and handled if found. An example of this is a feature dataset; its children are the feature classes it contains.  See the following code example:
[Java]
static void resolveNameConflicts(IEnumNameMapping enumNameMapping, IName targetName)
    throws Exception{
    // Iterate through each mapping in the enumerator.
    INameMapping nameMapping = null;
    while ((nameMapping = enumNameMapping.next()) != null){
        // See if the mapping itself has a conflict.
        if (nameMapping.isNameConflicts()){
            nameMapping.setTargetName(nameMapping.getSuggestedName(targetName));
        }
        // See if the mapping's children have conflicts.
        IEnumNameMapping childMapping = nameMapping.getChildren();
        if (childMapping != null){
            // Recursively check the child mappings for conflicts.
            childMapping.reset();
            resolveNameConflicts(childMapping, targetName);
        }
    }
}

Changing object names and keywords

After the IGeoDBDataTransfer.GenerateNameMapping call, you may wish to iterate through the object names and, if applicable, substitute your new name and keyword.  For example, if you wanted all programmatically copied datasets to have an extension, this would be useful. 
Since an INameMapping may have children, you may want to check them for children, at apply the same changes to them (as the following example does). In the following code example, an extension is added to the object name and the keyword is modified; there is no requirement to do both.
[Java]
// For example, targetSuffix = "_ext"
// configKeyword = "Default"
static void changeNameAndKeyword(IEnumNameMapping enumNameMapping, String
    targetSuffix, String configKeyword)throws Exception{
    // Iterate through each mapping in the enumerator.
    INameMapping nameMapping = null;
    while ((nameMapping = enumNameMapping.next()) != null){
        // Append the target name and set the config keyword.
        nameMapping.setTargetName(nameMapping.getTargetName() + targetSuffix);
        nameMapping.setConfigKeyword(configKeyword);
        // See if the mapping has children.
        IEnumNameMapping childMapping = nameMapping.getChildren();
        if (childMapping != null){
            // Recursively apply the changes.
            childMapping.reset();
            changeNameAndKeyword(childMapping, targetSuffix, configKeyword);
        }
    }
}
Changing the target names of mappings can create conflicts.  To prevent errors, it is recommended that mappings be checked for conflicts following a target name change.  The example above does not show this for the sake of simplicity.

Copy and pasting to a feature dataset

Copying and pasting datasets to a feature dataset is similar to copying and pasting datasets to the workspace level of a geodatabase, with one exception.  The IGeoDBDataTransfer.GenerateNameMapping and IGeoDBDataTransfer.Transfer methods should be passed a name object for the target feature dataset, rather than the workspace name.  The following code example shows a modified version of the TransferData method shown above that copies a dataset to a feature dataset:
[Java]
// For example, targetFeatureDataset = "Landbase"
static void transferData(IEnumName enumSourceName, IName workspaceName, String
    targetFeatureDataset)throws Exception{
    // Create the transfer object and a reference to a mapping enumerator.
    IGeoDBDataTransfer geoDBDataTransfer = new GeoDBDataTransfer();
    IEnumNameMapping enumNameMapping[] = new IEnumNameMapping[1];
    // Create a name object for the feature dataset.
    IFeatureDatasetName featureDatasetName = new FeatureDatasetName();
    IDatasetName datasetName = (IDatasetName)featureDatasetName;
    datasetName.setName(targetFeatureDataset);
    datasetName.setWorkspaceNameByRef((IWorkspaceName)workspaceName);
    IName targetName = (IName)featureDatasetName;
    // See if the transfer can proceed with the datasets' existing names.
    Boolean targetObjectsExist = geoDBDataTransfer.generateNameMapping
        (enumSourceName, targetName, enumNameMapping);
    enumNameMapping[0].reset();
    // See if any conflicts exist.
    if (targetObjectsExist){
        // Handle this in a way appropriate to the application.
        // See the ResolveNameConflicts method described at:
        // http://edndoc.esri.com/arcobjects/9.2/NET/67a4021b-a15d-4fd4-8114-7128f3a1e9ce.htm#Handling
        resolveNameConflicts(enumNameMapping[0], targetName);
    }
    // Transfer the data to the feature dataset.
    geoDBDataTransfer.transfer(enumNameMapping[0], targetName);
}


See Also:

How to connect to a geodatabase
How to convert simple data to a geodatabase




Additional Requirements
  • If working in ArcSDE, an ArcEditor or greater license will be needed in ArcGIS Desktop, and the Geodatabase Update extension will be required for ArcGIS Engine.
  • An ArcView license only supports copy and paste of simple features (feature classes [point, line, polygon] and feature datasets).

Development licensingDeployment licensing
ArcGIS for Desktop BasicArcGIS for Desktop Basic
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced
Engine Developer KitEngine