Select to view content in your preferred language

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

7690
16
Jump to solution
10-14-2014 02:45 AM
VesaLaakko
Occasional Contributor

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.

16 Replies
dotMorten_esri
Esri Notable Contributor

I'm still missing a few pieces. When you say "mki.Attributes["GLOBALID"]" is lower-case, I'm a little confused. What type is this attribute? I assume it's System.Guid and not string ? If it's System.Guid you will have to call "ToString()" on it to convert to a string-version - I'm not seeing that in your code (and again the string version doesn't "mean" anything - it's the 16 raw bytes that makes up the Guid that does).

If the attribute's type is "string", well that's an entirely different problem.

To put it another way: What does this return:  mki.Attributes["GLOBALID"].GetType()

If that returns "System.Guid" then the casing really means nothing (that's just the default way .NET converts guids to strings). If it returns "string", then we need to look at why your table schema defines the column as a string and not a guid.

Second, where are you getting the upper-case version from? I don't see that in your code.

0 Kudos
VesaLaakko
Occasional Contributor

Morten Nielsen wrote:

I'm still missing a few pieces. When you say "mki.Attributes["GLOBALID"]" is lower-case, I'm a little confused. What type is this attribute? I assume it's System.Guid and not string ?

In geodatabase type of that column is GLOBALID. I think runtime converts it to System.GUID. You should know it better.

Morten Nielsen wrote:

To put it another way: What does this return:  mki.Attributes["GLOBALID"].GetType()

{Name = "Guid" FullName = "System.Guid"}  

Morten Nielsen wrote:

Second, where are you getting the upper-case version from? I don't see that in your code.

It's stored in database before hand. table1.globalid={ADFF9CE5-D371-40DB-BB2A-9AB18AD68A2B} 

0 Kudos
dotMorten_esri
Esri Notable Contributor

Vesa Laakko wrote:

It's stored in database before hand. table1.globalid={ADFF9CE5-D371-40DB-BB2A-9AB18AD68A2B} 

I don't know your database or your schema, but if this field is a Guid type (and not a string type), the casing does not matter. It is just a difference in how .NET and whatever other software you're using to view the attribute (you still didn't specify where you got the upper-case version) displays guids. As mentioned the case does not matter as long as both attribute fields are of type guid. Some software doesn't even display the curly braces and others also skips the dashed lines. All of it doesn't matter, as this is merely a string representation of the real data underneath (similar to the date example I mentioned earlier which really is stored as a large number underneath)

As mentioned in the beginning we were not able to reproduce this and got it working just fine with 10.2.4. This makes me think there's something else at play here and the casing is just misleading you a little. There could be issues with how the relational table has been set up, or how you are performing your relational queries. Without a repro you can share, it's really hard to guess what's wrong here.

When you say "linkage is not established", so do you mean by that? What did you expect to be happening and how are you verifying that the linkage isn't there?

0 Kudos
VesaLaakko
Occasional Contributor

Morten Nielsen wrote:

When you say "linkage is not established", so do you mean by that? What did you expect to be happening and how are you verifying that the linkage isn't there?

I mean that those two items are not related to each other even if there is relationshipclass between those tables and relational field values are same except the casing. I saw this by ArcMap, there is a tool by which you can select related rows of another table and in this case selection result is empty. This lead me to think that casing matters anyway.

dotMorten_esri
Esri Notable Contributor
  • But how are you checking that?
  • Are you sure your changes got pushed back to the server?
  • Did you call ApplyEditsAsync on the ServiceFeatureTable?
  • And did you call myTable.AddAsync(newFeature) prior to that?
  • Did any errors occur? Did you check the network request being sent correctly? (use 'Fiddler').
0 Kudos
FreddieGibson
Honored Contributor

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

0 Kudos
DougBrowning
MVP Esteemed Contributor
0 Kudos