5 votos

Uniones de ArcObjects y campos no persistentes después de unirse a varias tablas

He heredado un proyecto ArcObjects verdaderamente horrible y muy grande que fue escrito originalmente en VB y luego portado a C#. Aparentemente el código fuente que me han dado no es la última versión y estoy persiguiendo errores por todas partes. El problema más desafiante va así...

Se están uniendo varias tablas (una tras otra) a una capa de características mediante IDisplayRelationshipClass.DisplayRelationshipClass . Llamemos a estas tablas A y B (hay más de 2). Cada una de estas tablas tiene los campos 1 y 2. Los objetos ITable se crean utilizando IFeatureWorkspace.OpenTable con un archivo DBF.

Después de la primera unión, si compruebo los campos de mi capa de características y al final puedo ver A.1 y A.2 (nombre de campo prefijado con el nombre del archivo DBF del que procede la tabla), ¡genial! Sin embargo, después de la segunda unión A.1 y A.2 han desaparecido, y en su lugar tengo B.1, B.2 - no tan bien...

¿Tengo que hacer algo para que los campos adicionales persistan en estas uniones, de modo que acabe con A.1, A.2, B.1, B.2, etc.? ? Si lo hago, o bien este comportamiento ha cambiado desde que se escribió el código por primera vez, o bien el código nunca ha funcionado. Dado que los campos están correctamente prefijados, no deberían sobrescribirse unos a otros.

Las uniones se producen así:

IMemoryRelationshipClassFactory pMemRelFact = new MemoryRelationshipClassFactoryClass();
IRelationshipClass pRelClass = pMemRelFact.Open("TabletoLayer", (IObjectClass)pTTable, dbfJnField, (IObjectClass)pFeatLayer.FeatureClass, layerJnField, "forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany);

IDisplayRelationshipClass pDispRC = (IDisplayRelationshipClass) pFeatLayer;
pDispRC.DisplayRelationshipClass(pRelClass, esriJoinType.esriLeftInnerJoin);

Cualquier ayuda con este tema sería muy apreciada.

EDITAR : Si esto ayuda, he observado algo bastante extraño. Después de la unión, pFeatLayer.FeatureClass.Fields.FieldsCount da el número original de campos antes de la unión, pero ((ITable)pFeatLayer.Fields.FieldsCount da el número esperado (con los campos unidos). Desafortunadamente, la variable pFeatLayer se pasa de nuevo a la función de unión, por lo que parece que las tablas se unen repetidamente contra el estado inicial de la capa de características, por lo que sólo la última unión hace una diferencia.

¿Alguna sugerencia de por qué un reparto de ITable daría un recuento de campos diferente al de la FeatureClass? ¿Es un error o simplemente un diseño tonto?

5voto

auramo Puntos 161

Este tema en la ayuda se ocupa de la unión de datos y puede ofrecer un mejor flujo de trabajo para su situación, aunque no estoy lo suficientemente familiarizado con él para decirlo con certeza.

En su respuesta a su edición, ITable respeta los campos unidos pero IFeatureClass no lo hace. Esto se insinúa en el ISelectionSet ayuda:

Si desea obtener un conjunto de selección en una capa de características, es una buena práctica lanzar la capa al ITable entonces utilice la interfaz ITable::Seleccionar método. La tabla que obtendrá de esta manera reflejará el contenido de la capa aunque tenga una consulta de definición o un join.

3voto

Stefan Thyberg Puntos 1546

La pregunta es antigua pero como me costó encontrar la respuesta a esto y acabé en esta página varias veces, pensé en complementar un poco la respuesta aceptada.

Encontré la solución en GeoNet de ESRI :

"Cuando se crea una unión en ArcMap, la unión da como resultado una tabla que es una combinación de las dos tablas que se han unido. Esta tabla se utiliza como fuente de visualización de la capa. Si desea añadir otra unión, deberá unir la tabla con el resultado de la primera unión. Esto dará como resultado una tabla que es la combinación de las 3 tablas. Puede hacerlo modificando su código para utilizar la clase de característica de visualización de la capa en lugar de su clase de característica (IGeoFeatureLayer.DisplayFeatureClass)."

Así que, en este caso, un código de trabajo sería

Type memRelClassFactoryType = Type.GetTypeFromProgID("esriGeodatabase.MemoryRelationshipClassFactory");
IMemoryRelationshipClassFactory memRelClassFactory = (IMemoryRelationshipClassFactory)Activator.CreateInstance(memRelClassFactoryType);
IGeoFeatureLayer gfLayer = pFeatLayer as IGeoFeatureLayer;
IRelationshipClass pRelClass = pMemRelFact.Open("TabletoLayer", (IObjectClass)pTTable, dbfJnField, (IObjectClass)gfLayer.DisplayFeatureClass, layerJnField, "forward", "backward", esriRelCardinality.esriRelCardinalityOneToMany);

IDisplayRelationshipClass pDispRC = (IDisplayRelationshipClass)gfLayer;
pDispRC.DisplayRelationshipClass(pRelClass, esriJoinType.esriLeftInnerJoin);

En lo anterior, también he sustituido la primera línea original

IMemoryRelationshipClassFactory pMemRelFact = new MemoryRelationshipClassFactoryClass();

con una forma diferente de crear IMemoryRelationshipClassFactory, esto parecía funcionar para mí. Así que, ¡gracias a Neil Clemmons!

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X