About getting a list of schema differences between replicas
To get the schema differences, first initialize the SchemaChanges class using the ISchemaChangesInit interface.
The interface provides three Init methods. All three require the target workspace to be specified. The target references the replica being compared to. Each method differs in how it allows the source to be referenced. The source is the replica to compare from.
If both replica geodatabases are on the same network, the source can be specified using the replica directly from the source geodatabase. If the geodatabases are on different networks, a replica schema file that describes the replica in the source geodatabase can be generated, sent, and used for the comparison. See the ReplicaSchemaExporter coclass and IExportSchema interface for how to generate the replica schema file.
The third way to specify the source is by using a replica schema differences file. This file already contains the schema differences between the replicas. See the ReplicaSchemaExporter co-class and IExportSchema interface for how to generate the replica schema differences file.
The following code example shows two methods to initialize the SchemaChange class. One method is for the case where the source replica is being compared against directly, and one is for either of the files previously described.
[C#]
// This function takes the two SDE workspaces and replica, and gets the schema changes.
public void ListSchemaChanges(IWorkspace targetWorkspace, IWorkspace sourceWorkspace,
String replicaName)
{
// Get the replica from the source and the workspace name object for the target.
IWorkspaceReplicas workspaceReplicas = (IWorkspaceReplicas)sourceWorkspace;
IReplica replica = workspaceReplicas.get_ReplicaByName(replicaName);
IDataset dataset = (IDataset)targetWorkspace;
IWorkspaceName workspaceName = (IWorkspaceName)dataset.FullName;
// Initialize the schema changes object.
ISchemaChanges schemaChanges = new SchemaChangesClass();
ISchemaChangesInit schemaChangesInit = (ISchemaChangesInit)schemaChanges;
schemaChangesInit.Init(replica, workspaceName);
// Print the changes.
PrintSchemaChanges(schemaChanges.GetChanges(), "");
}
// This function takes the target workspaces and either the schema file
// for the relative replica or a schema changes file, and gets the schema changes.
// Set the isSchemaChangeFile to true if it is a schema changes file.
public void ListSchemaChanges(IWorkspace targetWorkspace, String schemaFile, Boolean
isSchemaChangeFile)
{
// Workspace name object for the target.
IDataset dataset = (IDataset)targetWorkspace;
IWorkspaceName workspaceName = (IWorkspaceName)dataset.FullName;
// Initialize the schema changes object.
ISchemaChangesInit schemaChangesInit = (ISchemaChangesInit)new SchemaChanges();
if (isSchemaChangeFile)
{
schemaChangesInit.InitFromSchemaDifferencesDocument(schemaFile,
workspaceName);
}
else
{
schemaChangesInit.InitFromSchemaDocument(schemaFile, workspaceName);
}
ISchemaChanges schemaChanges = (ISchemaChanges)schemaChangesInit;
// Print the changes.
PrintSchemaChanges(schemaChanges.GetChanges(), "");
}
[VB.NET]
' This function takes the two SDE workspaces and replica, and gets the schema changes.
Public Sub ListSchemaChanges(ByVal targetWorkspace As IWorkspace, ByVal sourceWorkspace As IWorkspace, ByVal replicaName As String)
' Get the replica from the source and the workspace name object for the target.
Dim workspaceReplicas As IWorkspaceReplicas = CType(sourceWorkspace, IWorkspaceReplicas)
Dim replica As IReplica = workspaceReplicas.ReplicaByName(replicaName)
Dim dataset As IDataset = CType(targetWorkspace, IDataset)
Dim Name As IName = dataset.FullName
Dim workspaceName As IWorkspaceName = CType(Name, IWorkspaceName)
' Initialize the schema changes object.
Dim schemaChanges As ISchemaChanges = New SchemaChangesClass()
Dim schemaChangesInit As ISchemaChangesInit = CType(schemaChanges, ISchemaChangesInit)
schemaChangesInit.Init(replica, workspaceName)
' Print the changes.
PrintSchemaChanges(schemaChanges.GetChanges(), "")
End Sub
' This function takes the target workspaces and either the schema file
' for the relative replica or a schema changes file, and gets the schema changes.
' Set the isSchemaChangeFile to true if it is a schema changes file.
Public Sub ListSchemaChanges(ByVal targetWorkspace As IWorkspace, ByVal schemaFile As String, ByVal isSchemaChangeFile As Boolean)
' Workspace name object for the target.
Dim dataset As IDataset = CType(targetWorkspace, IDataset)
Dim Name As IName = dataset.FullName
Dim workspaceName As IWorkspaceName = CType(Name, IWorkspaceName)
' Initialize the schema changes object.
Dim schemaChangesInit As ISchemaChangesInit = New SchemaChangesClass()
If isSchemaChangeFile Then
schemaChangesInit.InitFromSchemaDifferencesDocument(schemaFile, workspaceName)
Else
schemaChangesInit.InitFromSchemaDocument(schemaFile, workspaceName)
End If
Dim schemaChanges As ISchemaChanges = CType(schemaChangesInit, ISchemaChanges)
' Print the changes.
Dim enumSchemaChange As IEnumSchemaChange = schemaChanges.GetChanges()
PrintSchemaChanges(enumSchemaChange, "")
End Sub
Calling the PrintSchemaChanges method
At the end of each procedure, the PrintSchemaChanges method is called. This method, provided with the following code example, prints the schema differences. It is a recursive method that takes an enumeration of schema changes. The enumeration returns objects that implement ISchemaChangeInfo. This interface describes the feature datasets, feature classes, fields, and other schema elements that have changed. It also describes the type of change needed for the target replica to be equivalent to the source replica. Each object can also return an enumeration that further describes the schema changes.
For example, if fields have been added to a feature class in a feature dataset of the source replica, an object is returned to describe that the feature dataset has changed. This object also returns an enumeration that includes an object to describe that the feature class has changed. This in turn, returns an enumeration, which has objects to describe each added field.
[C#]
// Recursive function that steps through the schema changes info.
public void PrintSchemaChanges(IEnumSchemaChange enumSchemaChanges, String
schemaChange)
{
enumSchemaChanges.Reset();
ISchemaChangeInfo schemaChangesInfo = null;
String dataName = "";
// Step through the schema changes.
while ((schemaChangesInfo = enumSchemaChanges.Next()) != null)
{
// Get the name of the feature class, feature dataset, and so on, that has changed.
if (schemaChangesInfo.SchemaChangeType !=
esriSchemaChangeType.esriSchemaChangeTypeNoChange)
{
if (schemaChangesInfo.ToObject != null)
{
dataName = GetDataName(schemaChangesInfo.ToObject);
}
else if (schemaChangesInfo.FromObject != null)
{
dataName = GetDataName(schemaChangesInfo.FromObject);
}
}
// If at the end of the list for the schema change, print the schema change.
// Otherwise, continue through the list.
if (schemaChangesInfo.GetChanges() != null)
{
String nextSchemaChange = String.Format("{0}{1}/", schemaChange,
dataName);
PrintSchemaChanges(schemaChangesInfo.GetChanges(), nextSchemaChange);
return ;
}
else
{
// Convert the schema change type to a string and print the change.
String changeType = Enum.GetName(typeof(esriSchemaChangeType),
schemaChangesInfo.SchemaChangeType);
Console.WriteLine("{0}{1}: {2}", schemaChange, dataName, changeType);
}
}
}
[VB.NET]
' Recursive function that steps through the schema changes info.
Public Sub PrintSchemaChanges(ByVal enumSchemaChanges As IEnumSchemaChange, ByVal schemaChange As String)
enumSchemaChanges.Reset()
Dim schemaChangesInfo As ISchemaChangeInfo = Nothing
Dim dataName As String = ""
' Step through the schema changes.
Do While Not (schemaChangesInfo) Is Nothing
' Get the name of the feature class, feature dataset, and so on, that has changed.
If schemaChangesInfo.SchemaChangeType <> esriSchemaChangeType.esriSchemaChangeTypeNoChange Then
Dim toObject As Object = schemaChangesInfo.ToObject
Dim fromObject As Object = schemaChangesInfo.FromObject
If Not toObject Is Nothing Then
dataName = GetDataName(toObject)
ElseIf Not fromObject Is Nothing Then
dataName = GetDataName(fromObject)
End If
End If
' If at the end of the list for the schema change, print the schema change.
' Otherwise, continue through the list.
If Not schemaChangesInfo.GetChanges() Is Nothing Then
Dim nextSchemaChange As String = String.Format("{0}{1}/", schemaChange, dataName)
PrintSchemaChanges(schemaChangesInfo.GetChanges(), nextSchemaChange)
Return
Else
' Convert the schema change type to a string and print the change.
Dim changeType As String = System.Enum.GetName(GetType(esriSchemaChangeType), schemaChangesInfo.SchemaChangeType)
Console.WriteLine("{0}{1}: {2}", schemaChange, dataName, changeType)
End If
schemaChangesInfo = enumSchemaChanges.Next()
Loop
End Sub
The following is an example of the output from this method:
BOB.USA_1/BOB.us_counties: esriSchemaChangeTypeDeleteTable
BOB.USA_1/BOB.us_cities: esriSchemaChangeTypeNewTable
BOB.USA_1/BOB.us_states/Field Changes/POP2006: esriSchemaChangeTypeNewField
BOB.USA_1/BOB.us_states/Field Changes/POP2000: esriSchemaChangeTypeDeleteField
BOB.USA_1/BOB.us_states/Field Changes/POP1990: esriSchemaChangeTypeDeleteField
BOB.USA_1/BOB.us_states/Field Changes/POP1996: esriSchemaChangeTypeDeleteField
BOB.USA_1/BOB.us_cities: esriSchemaChangeTypeNewTable
BOB.USA_1/BOB.us_states/Field Changes/POP2006: esriSchemaChangeTypeNewField
BOB.USA_1/BOB.us_states/Field Changes/POP2000: esriSchemaChangeTypeDeleteField
BOB.USA_1/BOB.us_states/Field Changes/POP1990: esriSchemaChangeTypeDeleteField
BOB.USA_1/BOB.us_states/Field Changes/POP1996: esriSchemaChangeTypeDeleteField
Each line in the output describes a different schema change. From these results, it is apparent that for the target replica to match the source replica, the following needs to be applied to the target:
- The us_counties table needs to be deleted.
- The us_cities table needs to be added.
- The POP2006 field needs to be added to the us_states table.
- The POP2000, POP1990, and POP1996 fields need to be deleted from the us_states table.
To apply these changes, augment the PrintSchemaChanges method and set the ISchemaChangeInfo.ApplySchemaChange property for the changes to apply. The ReplicaSchemaImporter is required to import the changes.
The previous PrintSchemaChanges method calls the following utility function. To run this code in applications, be sure to include this function. See the following code example:
[C#]
// Gets the name of the object returned from the schemachangesinfo class.
public String GetDataName(object data)
{
if (data is IDataElement)
{
IDataElement dataElement = (IDataElement)data;
return dataElement.Name;
}
else if (data is IFields)
{
return "Field Changes";
}
else if (data is IField)
{
IField field = (IField)data;
return field.Name;
}
else if (data is IDomain)
{
IDomain domain = (IDomain)data;
return domain.Name;
}
else
{
return "Unknown type";
}
}
[VB.NET]
' Gets the name of the object returned from the schemachangesinfo class.
Public Function GetDataName(ByVal data As Object) As String
If TypeOf data Is IDataElement Then
Dim dataElement As IDataElement = CType(data, IDataElement)
Dim dataElementName As String = dataElement.Name
Return dataElementName
ElseIf TypeOf data Is IFields Then
Return "Field Changes"
ElseIf TypeOf data Is IField Then
Dim field As IField = CType(data, IField)
Dim fieldName As String = field.Name
Return fieldName
ElseIf TypeOf data Is IDomain Then
Dim domain As IDomain = CType(data, IDomain)
Dim domainName As String = domain.Name
Return domainName
Else
Return "Unknown type"
End If
End Function
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.DataSourcesGDB ESRI.ArcGIS.System (ESRI.ArcGIS.esriSystem)ESRI.ArcGIS.Geodatabase ESRI.ArcGIS.GeoDatabaseDistributed
Development licensing | Deployment licensing |
---|---|
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |
Engine Developer Kit | Engine: Geodatabase Update |