Why globalid changes to lower case when getting GeodatabaseFeature.Attributes["GLOBALID"]?

6788
16
Jump to solution
10-14-2014 02:45 AM
VesaLaakko
New Contributor III

I have two ServiceFeaturetables combined with globalid based relationshipclass. When I try to create new GeodatabaseFeature and populate foreignkey, like feature2.attributes["SERVICEFEATURETABLE1_GLOBALID"]= feature1.attributes["GLOBALID"] , then the case of GLOBALID is changed to lower case and linkage between features will not be established.

1 Solution

Accepted Solutions
FreddieGibson
Occasional Contributor III

What is the problem?
The problem is centered behind having a relate between a GlobalId column and Guid column. When you add a Guid to a table in a feature service using Runtime it appears that this Guid will not be returned as a related record when the data is hosted in Oracle.

Why does this happen?

So far it appears that you'll run into this problem when using data hosted in an Oracle database. Although both the GlobalId and Guid columns are stored as char(38), the methods behind how the values are assigned to these columns result in different cases for the Guid's string representation. GlobalId values are auto-generated when records are added to the table and it appears that we add them to the table using their upper case string representation. On the other hand, when supplying a Guid value to the feature service via Runtime we're required to provide a Guid object and these values are stored as lower case strings on the database end by default. This behavior leads to conflicts in ArcMap when relating the two columns because they are compared as strings. In ArcMap you would notice that the Guid value {EF2E0C18-638C-4C6D-AFA7-4D23581CCAA5} would not be equivalent to {ef2e0c18-638c-4c6d-afa7-4d23581ccaa5} (i.e. the relate would show that there are no related records).

Can this issue be replicated without using runtime?

Technically yes, but not in necessarily the same manner. In ArcMap you could copy the GlobalId from one column, paste it into a related column, and convert it to lowercase. Once the GlobalId is stored in upper case and the related Guid column is stored in lower case these records would not recognize their values as the same. The primary difference between using ArcMap instead of Runtime would be that ArcMap will only allow you to supply the string to the Guid field. As such, you would have full control over the case of the string when you supply it to Oracle. In Runtime the feature service would require that you provide it a Guid object and the case of the resulting string would be determined by the RDBMS. It would just be important to note that the Guid wouldn't be a problem in databases like SQL Server where the Guid would be stored in upper case regardless of what you provide.

How to fix this issue?
In my testing I found that changing the case of the Guid column in ArcMap fixed the issue with the relate. I would assume that you could fix this issue on your end by doing one of the following:

1. Adding a constraint to my Guid column to make it always uppercase
2. Creating a trigger to convert the newly added Guid to upper case
3. Using an edit session in ArcMap to manually or programmatically update the values to upper case

View solution in original post

0 Kudos
16 Replies
dotMorten_esri
Esri Notable Contributor

What casing are you seeing reported by 'myTable.GlobalIDField' ? It's recommended you always use the properties rather than hardcoding the field values. Ie. change

      feature1.attributes["GLOBALID"]

to

      feature1.attributes[myTable.GlobalIDField]

0 Kudos
VesaLaakko
New Contributor III

I try to clarify my question. I have globalid value {ADFF9CE5-D371-40DB-BB2A-9AB18AD68A2B} in feature1 in Table1.

Between Table1 and Table2 there is a globalid based relationshipclass. So when I create new row in Table2, which I want to be related to feature1, I have to set foreign key field "Table1_globalid" to value feature1.globalid like Table2.Table1_globalid=Table1.globalid and with runtime API like feature2.attributes["TABLE1_GLOBALID"]= feature1.attributes["GLOBALID"]

For some reason when I take feature1.attributes["GLOBALID"] I get {adff9ce5-d371-40db-bb2a-9ab18ad68a2b}, so globalid value is changed to lower case value and no relationship was born.

0 Kudos
MichaelBranscomb
Esri Frequent Contributor

Hi,

Thanks for the clarification. I have entered an issue to investigate this further.

Cheers

Mike

0 Kudos
dotMorten_esri
Esri Notable Contributor

The string-representation shouldn't matter. Data is internally stored as raw GUID byte data. Try comparing them at the byte level by calling .ToByteArray() on the guid and check that the bytes are actually the same.

It's kind of the same as comparing "10/15/2014" with "Wednesday, October 15, 2014". They both represent the same date, but the string representation is different.

How are you getting the different string representations of the guids?

0 Kudos
VesaLaakko
New Contributor III

If the GUID's string-representation doesn't matter, why the relationship is broken in my example anyway? At least by ArcMap there is no relationship between these features. Looks like ArcMap (geodatabase?) works with string -representation anyway even if the values are GUIDs

0 Kudos
dotMorten_esri
Esri Notable Contributor

We attempted reproducing this but got it working. Would you happen to have a sample you can share that reproduces the issue?

0 Kudos
VesaLaakko
New Contributor III

A little bit difficult to share this sample, because our ArcGIS Server is not open to the internet. Did you get different casing from GUIDs and despite that, your relationship is working or do you have always same casing of values for both fields in your attempts?

0 Kudos
dotMorten_esri
Esri Notable Contributor

How did you get the string representations? Ie what code did you write to get two different casings of the GUIDs?

0 Kudos
VesaLaakko
New Contributor III

var MKITaulu = await Esri.ArcGISRuntime.Data.ServiceFeatureTable.OpenAsync(new Uri("http://smkdevserver.dev.local:6080/arcgis/rest/services/Kanto/FeatureServer/19"));

                MKITaulu.OutFields = OutFields.All;

                Feature mki = await MKITaulu.QueryAsync(2903);

                var tarkastusTaulu = await Esri.ArcGISRuntime.Data.ServiceFeatureTable.OpenAsync(new Uri("http://smkdevserver.dev.local:6080/arcgis/rest/services/Kanto/FeatureServer/39"));

                tarkastusTaulu.OutFields = OutFields.All;

                var newFeature = new Esri.ArcGISRuntime.Data.GeodatabaseFeature(tarkastusTaulu.Schema);

newFeature.Attributes["MKI_GLOBALID"] = mki.Attributes["GLOBALID"];<--this value is lower case

0 Kudos