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 databasesConverting 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):
ESRI.ArcGIS.System (ESRI.ArcGIS.esriSystem)ESRI.ArcGIS.Geodatabase ESRI.ArcGIS.Display
Development licensing | Deployment licensing |
---|---|
ArcGIS for Desktop Basic | ArcGIS for Desktop Basic |
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |
Engine Developer Kit | Engine |