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
Solved! Go to Solution.
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());
}
}
You can take a look at this ProSnippet: https://github.com/Esri/arcgis-pro-sdk/wiki/ProSnippets-Geodatabase#obtaining-related-definitions-fr...
@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.
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.
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
@NobbirAhmed Can you actually use this python code in C#?
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.
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());
}
}
In addition to calling
gdb.GetDefinitions<RelationshipClassDefinition>()
you should also call
gdb.GetDefinitions<AttributedRelationshipClassDefinition>()
--Rich
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.'"
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()}");
}
}
}