This document is archived and information here might be outdated.  Recommended version.


Copying and pasting geodatabase datasets (ArcObjects .NET 10.5 SDK)

Copying and pasting geodatabase datasets


Summary
The topic shows how to use the IGeoDBDataTransfer interface to copy data between two geodatabases. Also shown is how to handle naming conflicts when they arise, and 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 and a set containing different types of datasets.
The IGeoDBDataTransfer interface works with an ArcCatalog IGxDialog mini-browser. This example does not use an ArcCatalog IGxDialog mini-browser; therefore, the following objects must be created to utilize this functionality:
  • A name object for each dataset being copied. Creating these typically requires creating a name object for the datasets' workspace.
  • A name object for the target geodatabase.
  • An enumerator of source dataset names.
  • An enumerator of name mappings.
First, create IWorkspaceName objects for the two workspaces—the source workspace (that holds the dataset or datasets to be copied) and the target workspace. The following code example shows how to create name objects for both workspaces:
[C#]
// Create workspace name objects.
IWorkspaceName sourceWorkspaceName=new WorkspaceNameClass();
IWorkspaceName targetWorkspaceName=new WorkspaceNameClass();
IName targetName=(IName)targetWorkspaceName;

// Set the workspace name properties.
sourceWorkspaceName.PathName=@
    "C:\arcgis\ArcTutor\BuildingaGeodatabase\Montgomery.gdb";
sourceWorkspaceName.WorkspaceFactoryProgID=
    "esriDataSourcesGDB.FileGDBWorkspaceFactory";
targetWorkspaceName.PathName=@"PartialMontgomery.gdb";
targetWorkspaceName.WorkspaceFactoryProgID=
    "esriDataSourcesGDB.FileGDBWorkspaceFactory";
[VB.NET]
' Create workspace name objects.
Dim sourceWorkspaceName As IWorkspaceName=New WorkspaceName()
Dim targetWorkspaceName As IWorkspaceName=New WorkspaceName()

Dim targetName As IName=CType(targetWorkspaceName, IName)

' Set the workspace name properties.
sourceWorkspaceName.PathName="C:\arcgis\ArcTutor\BuildingaGeodatabase\Montgomery.gdb"
sourceWorkspaceName.WorkspaceFactoryProgID="esriDataSourcesGDB.FileGDBWorkspaceFactory"
targetWorkspaceName.PathName="PartialMontgomery.gdb"
targetWorkspaceName.WorkspaceFactoryProgID="esriDataSourcesGDB.FileGDBWorkspaceFactory"
If the target of a copy and paste operation is a feature dataset within a geodatabase, a name object should be created or retrieved for the feature dataset and used in place of the target workspace name.
A name object is also required for each dataset to be copied. By casting the source workspace to the IFeatureWorkspace interface and opening the dataset to be copied, a name object can be retrieved. See the following code example:
[C#]
// Create a name object for the source feature class.
IFeatureClassName featureClassName=new FeatureClassNameClass();

// Set the featureClassName properties.
IDatasetName sourceDatasetName=(IDatasetName)featureClassName;
sourceDatasetName.WorkspaceName=sourceWorkspaceName;
sourceDatasetName.Name="Blocks";
IName sourceName=(IName)sourceDatasetName;
[VB.NET]
' Create a name object for the source feature class.
Dim featureClassName As IFeatureClassName=New FeatureClassName()

' Set the featureClassName properties.
Dim sourceDatasetName As IDatasetName=CType(featureClassName, IDatasetName)
sourceDatasetName.WorkspaceName=sourceWorkspaceName
sourceDatasetName.Name="Blocks"
Dim sourceName As IName=CType(sourceDatasetName, IName)
An enumerator of name objects must be created for the dataset or datasets to be copied.  See the following code example:
[C#]
// Create an enumerator for source datasets.
IEnumName sourceEnumName=new NamesEnumeratorClass();
IEnumNameEdit sourceEnumNameEdit=(IEnumNameEdit)sourceEnumName;

// Add the name object for the source class to the enumerator.
sourceEnumNameEdit.Add(sourceName);
[VB.NET]
' Create an enumerator for source datasets.
Dim sourceEnumName As IEnumName=New NamesEnumerator()
Dim sourceEnumNameEdit As IEnumNameEdit=CType(sourceEnumName, IEnumNameEdit)

' Add the name object for the source class to the enumerator.
sourceEnumNameEdit.Add(sourceName)
Next, do the name mapping. If the IGeoDBDataTransfer.GenerateNameMapping method returns false, there are no name conflicts, and the copy and paste can be executed. If it returns true, there are name conflicts that need to be handled. See the following code example:
[C#]
// Create a GeoDBDataTransfer object and a null name mapping enumerator.
IGeoDBDataTransfer geoDBDataTransfer=new GeoDBDataTransferClass();
IEnumNameMapping enumNameMapping=null;

// Use the data transfer object to create a name mapping enumerator.
Boolean conflictsFound=geoDBDataTransfer.GenerateNameMapping(sourceEnumName,
    targetName, out enumNameMapping);
enumNameMapping.Reset();
[VB.NET]
' Create a GeoDBDataTransfer object and a null name mapping enumerator.
Dim geoDBDataTransfer As IGeoDBDataTransfer=New GeoDBDataTransfer()
Dim enumNameMapping As IEnumNameMapping=Nothing

' Use the data transfer object to create a name mapping enumerator.
Dim conflictsFound As Boolean=geoDBDataTransfer.GenerateNameMapping(sourceEnumName, targetWorkspaceName, enumNameMapping)
enumNameMapping.Reset()
Assuming no conflicts are found, the transfer can begin. See the following code example:
[C#]
// Start the transfer.
geoDBDataTransfer.Transfer(enumNameMapping, targetName);
[VB.NET]
' Start the transfer.
geoDBDataTransfer.Transfer(enumNameMapping, targetWorkspaceName)

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 INameMapping can 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:
[C#]
// Check for conflicts.
if (conflictsFound)
{
    // Iterate through each name mapping.
    INameMapping nameMapping=null;
    while ((nameMapping=enumNameMapping.Next()) != null)
    {
        // Resolve the mapping conflict (if there is one).
        if (nameMapping.NameConflicts)
        {
            nameMapping.TargetName=nameMapping.GetSuggestedName(targetName);
        }

        // See if the mapping's children have conflicts.
        IEnumNameMapping childEnumNameMapping=nameMapping.Children;
        if (childEnumNameMapping != null)
        {
            childEnumNameMapping.Reset();

            // Iterate through each child mapping.
            INameMapping childNameMapping=null;
            while ((childNameMapping=childEnumNameMapping.Next()) != null)
            {
                if (childNameMapping.NameConflicts)
                {
                    childNameMapping.TargetName=childNameMapping.GetSuggestedName
                        (targetName);
                }
            }
        }
    }
}
[VB.NET]
If conflictsFound Then
    ' Iterate through each name mapping.
    Dim nameMapping As INameMapping=enumNameMapping.Next()
    Do While Not nameMapping Is Nothing
        ' Resolve the mapping conflict (if there is one).
        If nameMapping.NameConflicts Then
            nameMapping.TargetName=nameMapping.GetSuggestedName(targetWorkspaceName)
        End If
        
        ' See if the mapping's children have conflicts.
        Dim childEnumNameMapping As IEnumNameMapping=nameMapping.Children
        If Not childEnumNameMapping Is Nothing Then
            childEnumNameMapping.Reset()
            
            ' Iterate through each child mapping.
            Dim childNameMapping As INameMapping=childEnumNameMapping.Next()
            Do While Not childNameMapping Is Nothing
                If childNameMapping.NameConflicts Then
                    childNameMapping.TargetName=childNameMapping.GetSuggestedName(targetWorkspaceName)
                End If
                
                childNameMapping=childEnumNameMapping.Next()
            Loop
        End If
        
        nameMapping=enumNameMapping.Next()
    Loop
End If

Changing object names and keywords

After the IGeoDBDataTransfer.GenerateNameMapping call, it is possible to iterate through the object names and substitute a new name or configuration keyword. This could be used, for example, to give all programmatically copied datasets a prefix or a suffix.
Since INameMapping can have children, it may be necessary to inspect them for children and apply the same changes to them (as in the following code example). In the following code example, an extension is added to the object name and the keyword is modified; keep in mind there is no requirement to do either.
[C#]
// Iterate through each name mapping.
enumNameMapping.Reset();
INameMapping nameMapping=null;
while ((nameMapping=enumNameMapping.Next()) != null)
{
    // Append a "_new" suffix to the mapping's target name.
    nameMapping.TargetName += "_new";

    // Iterate through the mapping's children.
    IEnumNameMapping childEnumNameMapping=nameMapping.Children;
    if (childEnumNameMapping != null)
    {
        childEnumNameMapping.Reset();

        // Iterate through each child mapping.
        INameMapping childNameMapping=null;
        while ((childNameMapping=childEnumNameMapping.Next()) != null)
        {
            childNameMapping.TargetName += "_new";
        }
    }
}
[VB.NET]
' Iterate through each name mapping.
enumNameMapping.Reset()
Dim nameMapping As INameMapping=enumNameMapping.Next()
Do While Not nameMapping Is Nothing
    ' Append a "_new" suffix to the mapping's target name.
    nameMapping.TargetName +="_new"
    
    ' Iterate through the mapping's children.
    Dim childEnumNameMapping As IEnumNameMapping=nameMapping.Children
    If Not childEnumNameMapping Is Nothing Then
        childEnumNameMapping.Reset()
        
        ' Iterate through each child mapping.
        Dim childNameMapping As INameMapping=childEnumNameMapping.Next()
        Do While Not childNameMapping Is Nothing
            childNameMapping.TargetName +="_new"
            childNameMapping=childEnumNameMapping.Next()
        Loop
    End If
    
    nameMapping=enumNameMapping.Next()
Loop
Changing the target names of mappings can create conflicts. To prevent errors, check mappings for conflicts following a target name change. The previous code example does not show this for the sake of simplicity. After changing the TargetName property, call INameMapping.ValidateTargetName (with the name object of the target as a parameter), then check the NameConflicts property. 

Complete code example

The following are complete code examples, with the exception of the "Changing object names and keywords" section:
[C#]
// Create workspace name objects.
IWorkspaceName sourceWorkspaceName=new WorkspaceNameClass();
IWorkspaceName targetWorkspaceName=new WorkspaceNameClass();
IName targetName=(IName)targetWorkspaceName;

// Set the workspace name properties.
sourceWorkspaceName.PathName=@
    "C:\arcgis\ArcTutor\BuildingaGeodatabase\Montgomery.gdb";
sourceWorkspaceName.WorkspaceFactoryProgID=
    "esriDataSourcesGDB.FileGDBWorkspaceFactory";
targetWorkspaceName.PathName=@"PartialMontgomery.gdb";
targetWorkspaceName.WorkspaceFactoryProgID=
    "esriDataSourcesGDB.FileGDBWorkspaceFactory";

// Create a name object for the source feature class.
IFeatureClassName featureClassName=new FeatureClassNameClass();

// Set the featureClassName properties.
IDatasetName sourceDatasetName=(IDatasetName)featureClassName;
sourceDatasetName.WorkspaceName=sourceWorkspaceName;
sourceDatasetName.Name="Blocks";
IName sourceName=(IName)sourceDatasetName;

// Create an enumerator for source datasets.
IEnumName sourceEnumName=new NamesEnumeratorClass();
IEnumNameEdit sourceEnumNameEdit=(IEnumNameEdit)sourceEnumName;

// Add the name object for the source class to the enumerator.
sourceEnumNameEdit.Add(sourceName);

// Create a GeoDBDataTransfer object and a null name mapping enumerator.
IGeoDBDataTransfer geoDBDataTransfer=new GeoDBDataTransferClass();
IEnumNameMapping enumNameMapping=null;

// Use the data transfer object to create a name mapping enumerator.
Boolean conflictsFound=geoDBDataTransfer.GenerateNameMapping(sourceEnumName,
    targetName, out enumNameMapping);
enumNameMapping.Reset();

// Check for conflicts.
if (conflictsFound)
{
    // Iterate through each name mapping.
    INameMapping nameMapping=null;
    while ((nameMapping=enumNameMapping.Next()) != null)
    {
        // Resolve the mapping's conflict (if there is one).
        if (nameMapping.NameConflicts)
        {
            nameMapping.TargetName=nameMapping.GetSuggestedName(targetName);
        }

        // See if the mapping's children have conflicts.
        IEnumNameMapping childEnumNameMapping=nameMapping.Children;
        if (childEnumNameMapping != null)
        {
            childEnumNameMapping.Reset();

            // Iterate through each child mapping.
            INameMapping childNameMapping=null;
            while ((childNameMapping=childEnumNameMapping.Next()) != null)
            {
                if (childNameMapping.NameConflicts)
                {
                    childNameMapping.TargetName=childNameMapping.GetSuggestedName
                        (targetName);
                }
            }
        }
    }
}

// Start the transfer.
geoDBDataTransfer.Transfer(enumNameMapping, targetName);
[VB.NET]
' Create workspace name objects.
Dim sourceWorkspaceName As IWorkspaceName=New WorkspaceName()
Dim targetWorkspaceName As IWorkspaceName=New WorkspaceName()

Dim targetName As IName=CType(targetWorkspaceName, IName)

' Set the workspace name properties.
sourceWorkspaceName.PathName="C:\arcgis\ArcTutor\BuildingaGeodatabase\Montgomery.gdb"
sourceWorkspaceName.WorkspaceFactoryProgID="esriDataSourcesGDB.FileGDBWorkspaceFactory"
targetWorkspaceName.PathName="PartialMontgomery.gdb"
targetWorkspaceName.WorkspaceFactoryProgID="esriDataSourcesGDB.FileGDBWorkspaceFactory"

' Create a name object for the source feature class.
Dim featureClassName As IFeatureClassName=New FeatureClassName()

' Set the featureClassName properties.
Dim sourceDatasetName As IDatasetName=CType(featureClassName, IDatasetName)
sourceDatasetName.WorkspaceName=sourceWorkspaceName
sourceDatasetName.Name="Blocks"

Dim sourceName As IName=CType(sourceDatasetName, IName)

' Create an enumerator for source datasets.
Dim sourceEnumName As IEnumName=New NamesEnumerator()

Dim sourceEnumNameEdit As IEnumNameEdit=CType(sourceEnumName, IEnumNameEdit)

' Add the name object for the source class to the enumerator.
sourceEnumNameEdit.Add(sourceName)

' Create a GeoDBDataTransfer object and a null name mapping enumerator.
Dim geoDBDataTransfer As IGeoDBDataTransfer=New GeoDBDataTransfer()
Dim enumNameMapping As IEnumNameMapping=Nothing

' Use the data transfer object to create a name mapping enumerator.
Dim conflictsFound As Boolean=geoDBDataTransfer.GenerateNameMapping(sourceEnumName, targetName, enumNameMapping)
enumNameMapping.Reset()

If conflictsFound Then
    ' Iterate through each name mapping.
    Dim nameMapping As INameMapping=enumNameMapping.Next()
    Do While Not nameMapping Is Nothing
        ' Resolve the mapping's conflict (if there is one).
        If nameMapping.NameConflicts Then
            nameMapping.TargetName=nameMapping.GetSuggestedName(targetName)
        End If
        
        ' See if the mapping's children have conflicts.
        Dim childEnumNameMapping As IEnumNameMapping=nameMapping.Children
        If Not childEnumNameMapping Is Nothing Then
            childEnumNameMapping.Reset()
            
            ' Iterate through each child mapping.
            Dim childNameMapping As INameMapping=childEnumNameMapping.Next()
            Do While Not childNameMapping Is Nothing
                If childNameMapping.NameConflicts Then
                    childNameMapping.TargetName=childNameMapping.GetSuggestedName(targetName)
                End If
                
                childNameMapping=childEnumNameMapping.Next()
            Loop
        End If
        
        nameMapping=enumNameMapping.Next()
    Loop
End If

' Start the transfer.
geoDBDataTransfer.Transfer(enumNameMapping, targetName)


See Also:

Connecting to geodatabases and databases
Converting simple data




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Additional Requirements
  • If working in ArcSDE, an ArcGIS Desktop Standard or Advanced license is needed, and the Geodatabase Update extension is required for ArcGIS Engine.
  • An ArcGIS Desktop Basic license only supports copy and paste of simple features (feature classes [point, line, polygon] and feature datasets).

Development licensing Deployment licensing
ArcGIS Desktop Basic ArcGIS Desktop Basic
ArcGIS Desktop Standard ArcGIS Desktop Standard
ArcGIS Desktop Advanced ArcGIS Desktop Advanced
Engine Developer Kit Engine