Select to view content in your preferred language

Join ignores the DefinitionExpression

838
6
02-18-2013 05:05 AM
InesImkamp
Deactivated User
I wrote the following code to get a FeatureClass with legend information corresponding to the map sheet (for example "TK=1234").
But the result of the join doesn't care of the DefinitionExpression.
When I do the same in ArcMap the result is how I expected. But programmatically

// 1. add a FeatureLayer from a FileGeoDatabase
IFeatureClass fcGeol = MyTools.LoadFeatureClass("FileGDB", sPath, "Geologische_Karten.gdb", sLayername);
IFeatureLayer2 flyrGeol = new FeatureLayerClass();
flyrGeol.FeatureClass = fcGeol;
ILayer lyrGeol = (ILayer)flyrGeol;
lyrGeol.Name = sLayername;
currentMap.AddLayer(lyrGeol);

// 2. add Table "Legenden" from "\Schichtenkatalog.mdb"ITable tabLegenden = MyTools.LoadTable("Access", sPath + "\\GeolLayers.mdb", "Legenden");

IStandaloneTable staloneTabLegenden = new StandaloneTableClass();
staloneTabLegenden.Table = tabLegenden;
staloneTabLegenden.Name = "Legenden";

// 3. set the DefinitionQuery !!!ITableDefinition tabdefLegenden = staloneTabLegenden as ITableDefinition;
tabdefLegenden.DefinitionExpression = "Legenden.TK = 1234";

// 4. add the Table "Legenden" to the StandaloneTableCollectionIStandaloneTableCollection standaloneTabColl = currentMap as IStandaloneTableCollection;
standaloneTabColl.AddStandaloneTable(staloneTabLegenden);

// 5. join the Table "Legenden" to the FeatureClassIDisplayRelationshipClass dispRelClass = flyrGeol as IDisplayRelationshipClass;
// create an InMemory-RelationshipClass-Objekt
Type t = Type.GetTypeFromProgID("esriGeodatabase.MemoryRelationshipClassFactory");
memrelFactory = Activator.CreateInstance(t) as IMemoryRelationshipClassFactory;
IRelationshipClass relationshipClass = memrelFactory.Open("Relation1",
(IObjectClass)fcGeol, "KOMBINR", (IObjectClass)staloneTabLegenden.Table, "KOMBINR",
"forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany);
dispRelClass.DisplayRelationshipClass(relationshipClass, esriJoinType.esriLeftOuterJoin);

// 5(b). attempt with DisplayTableIDisplayTable pDisplayTableLegend = staloneTabLegenden as IDisplayTable;
IRelationshipClass relationshipClass = memrelFactory.Open("Relation1",
(IObjectClass)fcGeol, "KOMBINR", (IObjectClass)pDisplayTableLegend.DisplayTable, "KOMBINR",
"forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany);
dispRelClass.DisplayRelationshipClass(relationshipClass, esriJoinType.esriLeftOuterJoin);

How can I get the join to notice my DefinitionExpression?

Thanks for your replies in advance.
Ines
0 Kudos
6 Replies
NeilClemmons
Honored Contributor
It looks to me like you're performing the join backwards.  In the Open() method, you pass in the table reference and its key field name first, followed by the feature class reference and its key field name.  This joins the table to the feature class.  Also, it looks like you're setting the definition query on the table?  Shouldn't you be setting it on the feature layer?
0 Kudos
InesImkamp
Deactivated User
Neil, thanks for reply.

It looks to me like you're performing the join backwards. In the Open() method, you pass in the table reference and its key field name first, followed by the feature class reference and its key field name. This joins the table to the feature class.

I tried to pass the table reference in the Open() method first:
IRelationshipClass relationshipClass = memrelFactory.Open("Relation1",
  (IObjectClass)staloneTabLegenden.Table, "KOMBINR", (IObjectClass)fcGeol, "KOMBINR",
  "forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany);

But the result is the same.

Also, it looks like you're setting the definition query on the table? Shouldn't you be setting it on the feature layer?

I have to set the definition query on the table, because the table contains the legend information for different feature classes. There are different TK with the same KOMBINR.
With the definition query I try to filter the TK of the current feature class (for instance TK=1234) and then I join the filtered table to the feature class. But in the result there are any TK, may be the first available, joined to the feature class.
The tables DefinitionExpression has no effect on the join result.
0 Kudos
NeilClemmons
Honored Contributor
Outline step by step what you have to do through the ArcMap UI in order to accomplish what you're wanting to do and I'll see if I can translate that to code.
0 Kudos
InesImkamp
Deactivated User
Here are the steps I would like to perform:

1. Add a feature class (one of several map sheets) to the map.

2. Add a table with legend informations (of all map sheets) to the StandaloneTableCollection.

3. Reduce the data in the table to the information for the current map sheet (Legenden.TK=...).

4. Join the reduced data to the feature class.
0 Kudos
InesImkamp
Deactivated User
Could anybody solve the problem???

If it doesn't work, I must copy the filtered data into a temporary table.
0 Kudos
InesImkamp
Deactivated User
Now I found a solution for my problem.
Because I'm working with a personal geodatabase I can load the table "Legenden" with IQueryName2 and IQueryDef.

// 1. add a FeatureLayer from a FileGeoDatabase
IFeatureClass fcGeol = MyTools.LoadFeatureClass("FileGDB", sPath, "Geologische_Karten.gdb", sLayername);
IFeatureLayer2 flyrGeol = new FeatureLayerClass();
flyrGeol.FeatureClass = fcGeol;
ILayer lyrGeol = (ILayer)flyrGeol;
lyrGeol.Name = sLayername;
currentMap.AddLayer(lyrGeol);

// 2. load the table "Legenden" with IQueryName2 and IQueryDef.
IFeatureWorkspace pFWS = MyTools.OpenAccessDbWorkspace(sDataPath, "GeolLayers.mdb") as IFeatureWorkspace;
IQueryDef pQueryDef = pFWS.CreateQueryDef();
pQueryDef.Tables = "Legenden";
pQueryDef.WhereClause = "Legenden.KartArt='GK50' AND Legenden.TK = 1234";
IQueryName2 pQName = new TableQueryNameClass() as IQueryName2;
pQName.QueryDef = pQueryDef;

// get a Name object for the Workspace
IDataset pDataset = (IDataset)pFWS;
IWorkspaceName pWSName = (IWorkspaceName)pDataset.FullName;

// cast the TableQueryName to the IDatasetName and open it
IDatasetName pDSName = (IDatasetName)pQName;
pDSName.WorkspaceName = pWSName;
IName pName = (IName)pQName;
ITable pTable = (ITable)pName.Open();

// 3. add the Table to the StandaloneTableCollection
IStandaloneTable staloneTabLegenden = new StandaloneTableClass();
staloneTabLegenden.Table = pTable;
staloneTabLegenden.Name = "Legenden";

IStandaloneTableCollection standaloneTabColl = currentMap as IStandaloneTableCollection;
standaloneTabColl.AddStandaloneTable(staloneTabLegenden);

// 4. join the Table "Legenden" to the FeatureClass
IDisplayRelationshipClass dispRelClass = flyrGeol as IDisplayRelationshipClass;
Type t = Type.GetTypeFromProgID("esriGeodatabase.MemoryRelationshipClassFactory");
memrelFactory = Activator.CreateInstance(t) as IMemoryRelationshipClassFactory;
IRelationshipClass relationshipClass = memrelFactory.Open("Relation1",
(IObjectClass)staloneTabLegenden.Table, "KOMBINR", (IObjectClass)fcGeol, "KOMBINR",
"forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany);
dispRelClass.DisplayRelationshipClass(relationshipClass, esriJoinType.esriLeftOuterJoin);

I hope this helps somebody else.
0 Kudos