ArcGIS Pro 3.4 API Reference Guide
ArcGIS.Desktop.Editing Namespace / RowToken Class
Members Example

In This Topic
    RowToken Class
    In This Topic
    A RowToken represents a feature that will be created but has not yet been created. It can be used in place of the object ID in referencing that feature even before it has an Object ID.
    Syntax
    public sealed class RowToken 
    Public NotInheritable Class RowToken 
    Remarks
    The RowToken can be used to chain together multiple editing primitives that depend on each other. For example, you can create two rows using Create(), and use the resulting RowTokens to create a utility network connectivity association.
    Example
    Edit Operation add attachment via RowToken
    //ArcGIS Pro 2.5 extends the EditOperation.AddAttachment method to take a RowToken as a parameter.
    //This allows you to create a feature, using EditOperation.CreateEx, and add an attachment in one transaction.
    
    var editOpAttach = new EditOperation();
    editOperation1.Name = string.Format("Create point in '{0}'", CurrentTemplate.Layer.Name);
    
    var attachRowToken = editOpAttach.Create(this.CurrentTemplate, polygon);
    editOpAttach.AddAttachment(attachRowToken, @"c:\temp\image.jpg");
    
    //Must be within a QueuedTask
    if (!editOpAttach.IsEmpty)
    {
      var result = editOpAttach.Execute(); //Execute and ExecuteAsync will return true if the operation was successful and false if not
    }
    Create a new Relationship and New Entities 1
    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"] = org_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 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"] = org_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
    internal static 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 "";
    }
    
    internal static 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 "";
    }
    
    internal async void AddDocumentRecord()
    {
    
      await QueuedTask.Run(() =>
      {
        using (var kg = GetKnowledgeGraph())
        {
          var edit_op = new EditOperation()
          {
            Name = "Create Document Example",
            SelectNewFeatures = true
          };
    
          var doc_entity_name = GetDocumentTypeName(kg.GetDataModel());
          if (string.IsNullOrEmpty(doc_entity_name))
            return false;
          var hasdoc_rel_name = GetHasDocumentTypeName(kg.GetDataModel());
          if (string.IsNullOrEmpty(hasdoc_rel_name))
            return false;
    
          //Document can also be FeatureClass
          var doc_tbl = kg.OpenDataset<Table>(doc_entity_name);
          var doc_rel_tbl = kg.OpenDataset<Table>(hasdoc_rel_name);
    
          //This is the document to be added...file, image, resource, etc.
          var 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"] = url;
          //Add geometry if relevant
          //attribs["Shape"] = doc_location;
    
          //optional
          attribs["fileExtension"] = System.IO.Path.GetExtension(url);
          attribs["text"] = System.IO.File.ReadAllText(url);
    
          //optional and arbitrary - your choice
          attribs["title"] = System.IO.Path.GetFileNameWithoutExtension(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.OpenDataset<FeatureClass>("Organization");
          var qf = new 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.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;
      });
    }
    
    Create utility network features and associations in a single edit operation
    // Create an EditOperation
    EditOperation editOperation = new EditOperation();
    editOperation.Name = "Create pole; create transformer bank; attach transformer bank to pole";
    
    // Create the transformer bank
    RowToken transformerBankToken = editOperation.Create(transformerBankLayer, transformerBankAttributes);
    
    // Create a pole
    RowToken poleToken = editOperation.Create(poleLayer, poleAttributes);
    
    // Create a structural attachment association between the pole and the transformer bank
    RowHandle poleHandle = new RowHandle(poleToken);
    RowHandle transformerBankHandle = new RowHandle(transformerBankToken);
    
    AssociationDescription poleAttachment = new AssociationDescription(AssociationType.Attachment, poleHandle, transformerBankHandle);
    
    editOperation.Create(poleAttachment);
    
    // Execute the EditOperation
    editOperation.Execute();
    
    Inheritance Hierarchy

    System.Object
       ArcGIS.Desktop.Editing.RowToken

    Requirements

    Target Platforms: Windows 11, Windows 10

    ArcGIS Pro version: 3 or higher.
    See Also