ArcGIS Pro 3.7 API Reference Guide
ArcGIS.Core.Data.Knowledge Namespace / KnowledgeGraphRelationshipType Class
Members Example

In This Topic
    KnowledgeGraphRelationshipType Class
    In This Topic
    Represents a relationship type in the knowledge graph.
    Syntax
    Public NotInheritable Class KnowledgeGraphRelationshipType 
       Inherits KnowledgeGraphNamedObjectType
       Implements System.IDisposable 
    public sealed class KnowledgeGraphRelationshipType : KnowledgeGraphNamedObjectType, System.IDisposable  
    Example
    Check Whether A Graph Type has a Spatial Property
    //Use GetDocumentEntityTypeName(KnowledgeGraphDataModel kg_dm) from
    //the 'Get Whether KG Has a Document Type' snippet to
    //get the documentNameType parameter
    bool HasGeometry(KnowledgeGraphNamedObjectType kg_named_obj)
    {
      var props = kg_named_obj.GetProperties();
      return props.Any(prop => prop.FieldType == FieldType.Geometry);
    }
    Get KnowledgeGraph Relationship Types
    {
      await QueuedTask.Run(() =>
      {
        //Create a connection properties
        var kg_props =
            new KnowledgeGraphConnectionProperties(new Uri(url));
        using (var kg = new KnowledgeGraph(kg_props))
        {
          //Get the KnowledgeGraph Data Model
          using (var kg_dm = kg.GetDataModel())
          {
            var dict_types = kg_dm.GetRelationshipTypes();
    
            foreach (var kvp in dict_types)
            {
              var rel_type = kvp.Value;
              var role = rel_type.GetRole();
              //note "name" will be the same name as the corresponding
              //feature class or table in the KG's relational gdb model
              var name = rel_type.GetName();
              //etc.
              //Get relationship end points
              var end_points = rel_type.GetEndPoints();
              foreach (var end_point in end_points)
              {
                System.Diagnostics.Debug.WriteLine(
                  $"Origin: '{end_point.GetOriginEntityTypeName()}', " +
                  $"Destination: '{end_point.GetDestinationEntityTypeName()}'");
              }
            }
    
          }
        }
      });
    }
    Create a new Relationship and New Entities 1
    {
      var mv = MapView.Active;
      var create_rel1 = await QueuedTask.Run(() =>
      {
        //This example uses a chained edit operation
        var edit_op = new EditOperation()
        {
          Name = "Create entities and a relationship",
          SelectNewFeatures = true
        };
    
        //We are just going to use the GDB objects in this one but
        //we could equally use feature layers/standalone tables
    
        //using Feature Class/Tables (works within Investigation or map)
        var org_fc = kg.OpenDataset<FeatureClass>("Organization");
        var person_tbl = kg.OpenDataset<Table>("Person");
        //Relationship table
        var emp_tbl = kg.OpenDataset<Table>("HasEmployee");
    
        var attribs = new Dictionary<string, object>();
    
        //New Organization
        attribs["Name"] = "Acme Ltd.";
        attribs["Description"] = "Specializes in household items";
        attribs["SHAPE"] = mv.Extent.Center;//whatever is its location
    
        //Add it to the operation - we need the rowtoken
        var rowtoken = edit_op.Create(org_fc, attribs);
    
        attribs.Clear();//we are going to re-use the dictionary
    
        //New Person
        attribs["Name"] = "Bob";
        attribs["Age"] = "41";
        attribs["Skills"] = "Plumbing, Framing, Flooring";
    
        //Add it to the operation
        var rowtoken2 = edit_op.Create(person_tbl, attribs);
    
        attribs.Clear();
    
        //At this point we must execute the create of the entities
        if (edit_op.Execute())
        {
          //if we are here, the create of the entities was successful
    
          //Next, "chain" a second create for the relationship - this ensures that
          //Both creates (entities _and_ relation) will be -undone- together if needed
          //....in other words they will behave as if they are a -single- transaction
          var edit_op_rel = edit_op.CreateChainedOperation();
    
          //we need the names of the origin and destination relation properties
          var kg_prop_info = kg.GetPropertyNameInfo();
          //use the row tokens we held on to from the entity creates
          attribs[kg_prop_info.OriginIDPropertyName] = rowtoken.GlobalID;
          attribs[kg_prop_info.DestinationIDPropertyName] = rowtoken2.GlobalID;
    
          //Add any extra attribute information for the relation as needed
          attribs["StartDate"] = new DateTimeOffset(DateTime.Now);
    
          //Do the create of the relate
          edit_op_rel.Create(emp_tbl, attribs);
          return edit_op_rel.Execute();
        }
        return false;//Create of entities failed
      });
    }
    Create a new Relationship and New Entities 2
    {
      var mv = MapView.Active;
      var createRel = await QueuedTask.Run(() =>
      {
        //This example uses a KnowledgeGraphRelationshipDescription
        var edit_op = new EditOperation()
        {
          Name = "Create entities and a relationship using a KG relate desc",
          SelectNewFeatures = true
        };
    
        //We are just going to use mapmembers in this example
        //we could equally use feature classes/tables
        var kg_layer = mv.Map.GetLayersAsFlattenedList()?
                      .OfType<ArcGIS.Desktop.Mapping.KnowledgeGraphLayer>().First();
        //From the KG Layer get the relevant child feature layer(s) and/or standalone
        //table(s)
        var org_fl = kg_layer.GetLayersAsFlattenedList().OfType<FeatureLayer>()
                        .First(child_layer => child_layer.Name == "Organization");
    
        var person_stbl = kg_layer.GetStandaloneTablesAsFlattenedList()
                        .First(child_layer => child_layer.Name == "Person");
    
        var rel_stbl = kg_layer.GetStandaloneTablesAsFlattenedList()
                        .First(child_layer => child_layer.Name == "HasEmployee");
    
        var attribs = new Dictionary<string, object>();
    
        //New Organization
        attribs["Name"] = "Acme Ltd.";
        attribs["Description"] = "Specializes in household items";
        attribs["SHAPE"] = mv.Extent.Center;//whatever is its location
    
        //Add it to the operation - we need the rowtoken
        var rowtoken_org = edit_op.Create(org_fl, attribs);
    
        attribs.Clear();//we are going to re-use the dictionary
    
        //New Person
        attribs["Name"] = "Bob";
        attribs["Age"] = "41";
        attribs["Skills"] = "Plumbing, Framing, Flooring";
    
        //Add it to the operation
        var rowtoken_person = edit_op.Create(person_stbl, attribs);
    
        attribs.Clear();
    
        //Create the new relationship using a KnowledgeGraphRelationshipDescription
        //Row handles act as the placeholders for the TO BE created new entities that will
        //be related
        var src_row_handle = new RowHandle(rowtoken_org);
        var dest_row_handle = new RowHandle(rowtoken_person);
    
        //Add any extra attribute information for the relation as needed
        attribs["StartDate"] = new DateTimeOffset(DateTime.Now);
    
        var rel_desc = new KnowledgeGraphRelationshipDescription(
                                    src_row_handle, dest_row_handle, attribs);
    
        //Add the relate description to the edit operation
        edit_op.Create(rel_stbl, rel_desc);
    
        //Execute the create of the entities and relationship
        return edit_op.Execute();
      });
    }
    Create a Document Record 1
    {
      var ok = await QueuedTask.Run(() =>
      {
        using (var kg_for_doc = kgLayer.GetDatastore())
        {
          var edit_op = new EditOperation()
          {
            Name = "Create Document Example",
            SelectNewFeatures = true
          };
    
          var doc_entity_name = GetDocumentTypeName(kg_for_doc.GetDataModel());
          if (string.IsNullOrEmpty(doc_entity_name))
            return false;
          var hasdoc_rel_name = GetHasDocumentTypeName(kg_for_doc.GetDataModel());
          if (string.IsNullOrEmpty(hasdoc_rel_name))
            return false;
    
          //Document can also be FeatureClass
          var doc_tbl = kg_for_doc.OpenDataset<Table>(doc_entity_name);
          var doc_rel_tbl = kg_for_doc.OpenDataset<Table>(hasdoc_rel_name);
    
          //This is the document to be added...file, image, resource, etc.
          var doc_url = @"E:\Data\Temp\HelloWorld.txt";
          var text = System.IO.File.ReadAllText(url);
    
          //Set document properties
          var attribs = new Dictionary<string, object>();
          attribs["contentType"] = @"text/plain";
          attribs["name"] = System.IO.Path.GetFileName(url);
          attribs["url"] = doc_url;
          //Add geometry if relevant
          //attribs["Shape"] = doc_location;
    
          //optional
          attribs["fileExtension"] = System.IO.Path.GetExtension(doc_url);
          attribs["text"] = System.IO.File.ReadAllText(doc_url);
    
          //optional and arbitrary - your choice
          attribs["title"] = System.IO.Path.GetFileNameWithoutExtension(doc_url);
          attribs["keywords"] = @"text,file,example";
          attribs["metadata"] = "";
    
          //Specify any additional custom attributes added to the document
          //schema by the user as needed....
          //attribs["custom_attrib"] = "Foo";
          //attribs["custom_attrib2"] = "Bar";
    
          //Get the entity whose document this is...
          var org_fc = kg_for_doc.OpenDataset<FeatureClass>("Organization");
          var qf = new ArcGIS.Core.Data.QueryFilter()
          {
            WhereClause = "name = 'Acme'",
            SubFields = "*"
          };
          var origin_org_id = Guid.Empty;
          using (var rc = org_fc.Search(qf))
          {
            if (!rc.MoveNext())
              return false;
            origin_org_id = rc.Current.GetGlobalID();//For the relate
          }
    
          //Create the document row/feature
          var rowtoken = edit_op.Create(doc_tbl, attribs);
          if (edit_op.Execute())
          {
            //Create the relationship row
            attribs.Clear();
            //we need the names of the origin and destination relation properties
            var kg_prop_info = kg_for_doc.GetPropertyNameInfo();
            //Specify the origin entity (i.e. the document 'owner') and
            //the document being related to (i.e. the document 'itself')
            attribs[kg_prop_info.OriginIDPropertyName] = origin_org_id;//entity
            attribs[kg_prop_info.DestinationIDPropertyName] = rowtoken.GlobalID;//document
    
            //Specify any custom attributes added to the has document
            //schema by the user as needed....
            //attribs["custom_attrib"] = "Foo";
            //attribs["custom_attrib2"] = "Bar";
    
            //"Chain" a second create for the relationship - this ensures that
            //Both creates (doc _and_ "has doc" relation) will be -undone- together if needed
            //....in other words they will behave as if they are a -single- transaction
            var edit_op_rel = edit_op.CreateChainedOperation();
            edit_op_rel.Create(doc_rel_tbl, attribs);
            return edit_op_rel.Execute();
          }
          return false;
        }
      });
    }
    
    string GetDocumentTypeName(KnowledgeGraphDataModel kg_dm)
    {
      var entity_types = kg_dm.GetEntityTypes();
      foreach (var entity_type in entity_types)
      {
        var role = entity_type.Value.GetRole();
        if (role == KnowledgeGraphNamedObjectTypeRole.Document)
          return entity_type.Value.GetName();
      }
      return "";
    }
    
    string GetHasDocumentTypeName(KnowledgeGraphDataModel kg_dm)
    {
      var rel_types = kg_dm.GetRelationshipTypes();
      foreach (var rel_type in rel_types)
      {
        var role = rel_type.Value.GetRole();
        if (role == KnowledgeGraphNamedObjectTypeRole.Document)
          return rel_type.Value.GetName();
      }
      return "";
    }
    Delete an Entity record
    {
      var mv = MapView.Active;
      await QueuedTask.Run(() =>
      {
        var edit_op = new EditOperation()
        {
          Name = "Delete an Entity record"
        };
    
        //We are  going to use mapmembers in this example
        //we could equally use feature classes/tables
        var kg_layer = mv.Map.GetLayersAsFlattenedList()?
                      .OfType<ArcGIS.Desktop.Mapping.KnowledgeGraphLayer>().First();
        //Entity
        var org_fl = kg_layer.GetLayersAsFlattenedList().OfType<FeatureLayer>()
                        .First(child_layer => child_layer.Name == "Organization");
    
        //Get the entity feature(s) to delete
        long org_oid = -1;
        var qf = new ArcGIS.Core.Data.QueryFilter()
        {
          WhereClause = "name = 'Acme'",
          SubFields = "*"
        };
        using (var rc = org_fl.Search(qf))
        {
          if (!rc.MoveNext())
            return;//nothing to delete
          org_oid = rc.Current.GetObjectID();
        }
    
        edit_op.Delete(org_fl, org_oid);
        edit_op.Execute();//Do the delete
      });
    }
    Delete a Relationship record 1
    {
      var mv = MapView.Active;
      await QueuedTask.Run(() =>
      {
        var edit_op = new EditOperation()
        {
          Name = "Delete a Relationship record"
        };
    
        //We are  going to use mapmembers in this example
        //we could equally use feature classes/tables
        var kg_layer = mv.Map.GetLayersAsFlattenedList()?
                      .OfType<ArcGIS.Desktop.Mapping.KnowledgeGraphLayer>().First();
        //Relationship
        var rel_stbl = kg_layer.GetStandaloneTablesAsFlattenedList()
                        .First(child_layer => child_layer.Name == "HasEmployee");
    
        //Get the relation row to delete
        long rel_oid = -1;
        using (var rc = rel_stbl.Search())
        {
          if (!rc.MoveNext())
            return;
          //arbitrarily, in this example, get the first row
          rel_oid = rc.Current.GetObjectID();
        }
    
        edit_op.Delete(rel_stbl, rel_oid);
        edit_op.Execute();//Do the delete
      });
    }
    Delete a Relationship record 2
    {
      var mv = MapView.Active;
      await QueuedTask.Run(() =>
      {
    
        var edit_op = new EditOperation()
        {
          Name = "Delete a Relationship record"
        };
    
        //We are  going to use mapmembers in this example
        //we could equally use feature classes/tables
        var kg_layer = mv.Map.GetLayersAsFlattenedList()?
                      .OfType<ArcGIS.Desktop.Mapping.KnowledgeGraphLayer>().First();
    
        //entities
        var entityOrg = kg_layer.GetStandaloneTablesAsFlattenedList()
                        .First(child_layer => child_layer.Name == "Organization");
        var entityPerson = kg_layer.GetStandaloneTablesAsFlattenedList()
                        .First(child_layer => child_layer.Name == "Person");
    
        //Relationship
        var rel_stbl = kg_layer.GetStandaloneTablesAsFlattenedList()
                        .First(child_layer => child_layer.Name == "HasEmployee");
    
        // get the origin, destination records
        Guid guidOrigin = Guid.Empty;
        Guid guidDestination = Guid.Empty;
        using (var rc = entityOrg.Search())
        {
          if (rc.MoveNext())
            //Use the KnowledgeGraphPropertyInfo to avoid hardcoding...
            guidOrigin = rc.Current.GetGlobalID();
        }
        using (var rc = entityPerson.Search())
        {
          if (rc.MoveNext())
            //Use the KnowledgeGraphPropertyInfo to avoid hardcoding...
            guidDestination = rc.Current.GetGlobalID();
        }
    
        var rd = new KnowledgeGraphRelationshipDescription(guidOrigin, guidDestination);
        edit_op.Delete(rel_stbl, rd);
        edit_op.Execute();//Do the delete
      });
    }
    Inheritance Hierarchy

    System.Object
       ArcGIS.Core.CoreObjectsBase
          ArcGIS.Core.Data.Knowledge.KnowledgeGraphNamedObjectType
             ArcGIS.Core.Data.Knowledge.KnowledgeGraphRelationshipType

    Requirements

    Target Platforms: Windows 11 Home, Pro, Enterprise (64 bit)

    ArcGIS Pro version: 3.2 or higher.
    See Also