Check if feature class/table has a relationship and return it pro sdk

806
9
Jump to solution
01-12-2021 10:53 AM
MarvisKisakye1
Occasional Contributor

Is there a way to check if a feature class/table has a relationship and if so, to return that relationship for further processing?@UmaHarano @Wolf @RichRuh @NobbirAhmed 

Tags (2)
1 Solution

Accepted Solutions
KirkKuykendall1
Occasional Contributor III

This works for me

public static void TestGetRelates()
{
    foreach (var def in GetRelates(@"E:\some.gdb", "somefeatclass"))
    {
        Debug.Print($"{def.GetName()} {def.GetOriginClass()} {def.GetDestinationClass()}");
    }
}
public static IEnumerable<RelationshipClassDefinition> GetRelates(string fgdbPath, string fcName)
{
    using (var gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(fgdbPath))))
    {
        return gdb.GetDefinitions<RelationshipClassDefinition>()
        .Where(
            def => def.GetOriginClass().Trim().ToUpper() == fcName.Trim().ToUpper()
            || def.GetDestinationClass().Trim().ToUpper() == fcName.Trim().ToUpper());
    }
}

View solution in original post

9 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor
MarvisKisakye1
Occasional Contributor

@Wolf  I see this line 

 RelationshipClassDefinition enterpriseDefinition = geodatabase.GetDefinition<RelationshipClassDefinition>("LocalGovernment.GDB.AddressPointHasSiteAddresses");

but in my case I don't have the name of the relationship class. I just have the feature class that has the relationship. The link you sent I believe requires that you have the name of the  relationship class.

Wolf
by Esri Regular Contributor
Esri Regular Contributor

Sorry I about the delayed response, I didn't have enough time earlier to reply with a more general code snippet so I just posted the link real quick, but I see from your post above that you figured it out in the meantime.  

0 Kudos
NobbirAhmed
Esri Regular Contributor

In Python (@Wolf - it would be great if you can translate the python syntax into C#). I'll also try.

d = arcpy.Descrbibe("input_data")

relation_class = d.relationshipClassNames

# returns relationship class(es) the dataset participate in

0 Kudos
MarvisKisakye1
Occasional Contributor

@NobbirAhmed  Can you actually use this python code in C#?

0 Kudos
NobbirAhmed
Esri Regular Contributor

No - we cannot use python code in C# "as is" - this is just for an idea. If Python has the ability to read - I'm hopefull C# SDK might have a way. Let's wait for Wolf's response.

0 Kudos
KirkKuykendall1
Occasional Contributor III

This works for me

public static void TestGetRelates()
{
    foreach (var def in GetRelates(@"E:\some.gdb", "somefeatclass"))
    {
        Debug.Print($"{def.GetName()} {def.GetOriginClass()} {def.GetDestinationClass()}");
    }
}
public static IEnumerable<RelationshipClassDefinition> GetRelates(string fgdbPath, string fcName)
{
    using (var gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(fgdbPath))))
    {
        return gdb.GetDefinitions<RelationshipClassDefinition>()
        .Where(
            def => def.GetOriginClass().Trim().ToUpper() == fcName.Trim().ToUpper()
            || def.GetDestinationClass().Trim().ToUpper() == fcName.Trim().ToUpper());
    }
}

View solution in original post

RichRuh
Esri Regular Contributor

In addition to calling

gdb.GetDefinitions<RelationshipClassDefinition>()

you should also call

gdb.GetDefinitions<AttributedRelationshipClassDefinition>()

 

--Rich

KirkKuykendall1
Occasional Contributor III

Oops ... I completely forgot that GetDefinitions isn't SOLID - it doesn't honor Liskov substitution

For example, Geodatabase.GetDefinitions<Definition>() compiles, but raises a run-time exception:

"This type of geodatabase (LocalDatabase) does not currently support definition of type Definition.'"

KirkKuykendall1_0-1611160295105.png

 

The code below works with both attributed and regular relationshipclass definitions.  If Esri ever introduces another relationship type that's a subclass of RelationshipClassDefinition, this code will need to be modified.  (Thanks @RichRuh !)

public static class ExtensionMethods
{
    public static IEnumerable<RelationshipClassDefinition> 
            GetRelates(this Geodatabase gdb, string fcName)
    {
        return gdb.GetDefinitions<RelationshipClassDefinition>()
        .Where(def => def.Involves(fcName))
        .Concat(gdb.GetDefinitions<AttributedRelationshipClassDefinition>())
        .Where(def => def.Involves(fcName));
    }
    public static bool Involves(this RelationshipClassDefinition def1, string fcName)
    {
        return def1.GetDestinationClass().CIEquals(fcName) 
                || def1.GetOriginClass().CIEquals(fcName);
    }
    public static bool CIEquals(this string s1, string s2)
    {
        return s1.Trim().Equals(s2.Trim(),StringComparison.OrdinalIgnoreCase);
    }
}

public static void TestGetRelates()
{
    string fgdbPath = @"E:\somedatabase.gdb";
    string fcName = " someTable ";
    using (var gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(fgdbPath))))
    {
        foreach(var def in gdb.GetRelates(fcName))
        {
            Debug.Print($"{def.GetName()} {def.GetOriginClass()} {def.GetDestinationClass()}");
        }
    }
}