I'm trying to join an external table to a IGeoFeatureLayer, and it works well. The problem is when I save this map and then reload the .mxd, the FeatureClass of the layer is null, and the Table of Contents shows a warning symbol next to the layer. Is it failing to serialize/deserialize the joined feature class? What is the correct approach to solve this problem?Here's the code I'm using:
string externalFields = GetExternalFields(joinFields);
ITable table = GetExternalTable(externalFields);
geoFeatureLayer.FeatureClass = CreateFeatureClass(table, externalFields);
// ...
private ITable GetExternalTable(string externalFields)
{
IWorkspaceFactory2 workspaceFactory2;
IWorkspace workspace;
ISqlWorkspace sqlWorkspace;
ITable table;
using (var comReleaser = new ComReleaser())
{
var query = string.Format(
QUERY_BASE, externalFields, synchronizer.LayerManager.ParcelLayer.GetParcelYear()
);
var factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SqlWorkspaceFactory");
workspaceFactory2 = Activator.CreateInstance(factoryType) as IWorkspaceFactory2;
workspace = workspaceFactory2.OpenFromString(this.connection, 0);
sqlWorkspace = workspace as ISqlWorkspace;
comReleaser.ManageLifetime(workspaceFactory2);
comReleaser.ManageLifetime(sqlWorkspace);
var queryDescription = sqlWorkspace.GetQueryDescription(query);
queryDescription.OIDFields = EXTERNAL_KEY;
var datasetName = "S";
sqlWorkspace.CheckDatasetName("S", queryDescription, out datasetName);
table = sqlWorkspace.OpenQueryClass(datasetName, queryDescription);
}
return table;
}
private IFeatureClass CreateFeatureClass(ITable externalTable, string externalFields)
{
IGeoFeatureLayer geoFeatureLayer = synchronizer.LayerManager.ParcelLayer as IGeoFeatureLayer;
IMemoryRelationshipClassFactory memoryRelationshipFactory = null;
IRelQueryTableFactory relQueryTableFactory = null;
IRelQueryTable relQueryTable = null;
try
{
var memoryRelationshipClassFactory = Type.GetTypeFromProgID("esriGeodatabase.MemoryRelationshipClassFactory");
memoryRelationshipFactory = Activator.CreateInstance(memoryRelationshipClassFactory) as IMemoryRelationshipClassFactory;
var relationshipClass = memoryRelationshipFactory.Open(
"Join",
geoFeatureLayer.DisplayFeatureClass as IObjectClass,
FEATURE_KEY, externalTable as IObjectClass, EXTERNAL_KEY,
"forward", "backward", esriRelCardinality.esriRelCardinalityOneToOne
);
var relQueryTableFactoryType = Type.GetTypeFromProgID("esriGeodatabase.RelQueryTableFactory");
relQueryTableFactory = Activator.CreateInstance(relQueryTableFactoryType) as IRelQueryTableFactory;
relQueryTable = relQueryTableFactory.Open(
relationshipClass, true, null, null, externalFields, true, true
) as IRelQueryTable;
}
finally
{
Marshal.FinalReleaseComObject(memoryRelationshipFactory);
Marshal.FinalReleaseComObject(relQueryTableFactory);
}
return relQueryTable as IFeatureClass;
}
}