Edit operation not deleting rows in table

623
15
Jump to solution
10-25-2022 09:22 AM
succip
by
New Contributor III

Hello,

I'm having an issue deleting rows from a table using the EditOperation class. My code is as follows:

QueuedTask.Run(() => { Table dnoXrefTable = Utilities.GetPrdTable("SPATIAL.DNO_XREF"); QueryFilter qf = new QueryFilter { WhereClause = $"FACILITYID='{facilityId}' AND FEATURECLASS='{featureClassName}'" }; var deleteOperation = new EditOperation(); deleteOperation.Name = "Delete features"; using (var rowCursor = dnoXrefTable.Search(qf, false)) { while (rowCursor.MoveNext()) { using (var row = rowCursor.Current) { deleteOperation.Delete(row); } } } deleteOperation.Execute(); });

No errors but data isn't removed from the table after it runs. I can delete the features manually so I don't think it's a permissions issue.

Thanks in advance for any help!

Tags(1)
0Kudos
15 Replies
Wolf
by 金宝搏吧
金宝搏吧

So you see the "Objectid: ..." output for multiple records but only the last record is being deleted? I have implemented the same scenario also with a one-to-many relationship and all my related records are deleted.

Which release of ArcGIS Pro are you using?

0Kudos
succip
by
New Contributor III

Yep, I see see each unique ObjectID in the output. I'm on ArcGIS Pro 3.0.0, I will try updating to the latest version.

Maybe also worth mentioning: I have a similar function somewhere else in my add-in, but this is tied to a dockpane to allow users to delete entries manually. The code here is as follows, with the main difference (as far as I can see) being this doesn't use the RowDeletedEvent:

public ICommand CmdDeleteDrawing { get { return new RelayCommand(() => { if (_selectedDrawingEntry == null) { MessageBox.Show("Please select a drawing to remove first."); } else { QueuedTask.Run(async () => { Table dnoXrefTable = Utilities.GetPrdTable("SPATIAL.DNO_XREF"); var deleteDrawing = new EditOperation(); deleteDrawing.Name = "Delete Drawing"; QueryFilter qf = new QueryFilter { WhereClause = $"DNO_ID={_selectedDrawingEntry.DnoId} AND FACILITYID={_selectedDrawingEntry.FacilityId}" }; RowCursor rc = dnoXrefTable.Search(qf, false); while (rc.MoveNext()) { Row dr = rc.Current; deleteDrawing.Delete(dr); deleteDrawing.Execute(); await Project.Current.SaveEditsAsync(); } }); } }); } }

This method works no problem.

0Kudos
Wolf
by 金宝搏吧
金宝搏吧

Actually, after i tried your use case with my code snippet again i realized that my dataset didn't really represent the one-to-many (related records) use case property, instead with my data i always only had one related record that was correctly deleted. After changing my query logic, i was able to duplicate the same problem that you are seeing. I think that this is actually a bug. I will pass this on to the Editor team.

However, there is a workaround for this issue. You can use the EditOperation Delete method on the table instead of deleting each row. The following code snippet worked for me:

// collect all object ids that need to be deleted List ids = new List(); using (var tableCursor = _countyTable.Search(qf)) { while (tableCursor.MoveNext()) { using (var tableRow = tableCursor.Current) { //not working as expected: deleteEditOp.Delete(tableRow); ids.Add(tableRow.GetObjectID()); } } } // delete all records with objects ids deleteEditOp.Delete(_countyTable, ids);

Can you check if this works for you?

succip
by
New Contributor III

Yes, that works! What a relief, thank you again for your help.

0Kudos
succip
by
New Contributor III

Sorry Wolf if I could add one more addendum to this: I'm still having issues deleting records from the table using DatabaseConnectionProperties instead of through the ToC and I'm wondering if this is also a bug. Running with breakpoints I see the table is populated but nothing is deleted after it finishes. Accessing this table in my other dockpane using the same code works as expected, but only has issues in the RowDeletedEvent.

protected static void OnRowDeletedEvent(RowChangedEventArgs args) { DatabaseConnectionProperties connectionProperties = new DatabaseConnectionProperties(EnterpriseDatabaseType.Oracle) { AuthenticationMode = AuthenticationMode.DBMS, User = "user", Password = "password", Instance = @"instance" }; Geodatabase geodatabase = new Geodatabase(connectionProperties); Table dnoTable = geodatabase.OpenDataset("SPATIAL.DNO_XREF"); var deleteOperation = args.Operation; QueryFilter qf = new QueryFilter { WhereClause = $"FACILITYID='{args.Row["FACILITYID"]}' AND FEATURECLASS='{args.Row.GetTable().GetDefinition().GetModelName()}'" }; List oids = new List(); using (var rc = dnoTable.Search(qf)) { while (rc.MoveNext()) { using (var deleteRow = rc.Current) { oids.Add(deleteRow.GetObjectID()); } } } deleteOperation.Delete(dnoTable, oids); }
                         

0Kudos
Wolf
by 金宝搏吧
金宝搏吧

There are two issues i can see here:

1) When you use: 'var deleteOperation = args.Operation;' meaning you try to use the existing (executing) EditOperation, you cannot include a table or feature class that is not already on the map (table of content) during that edit session. In other words, you can only include tables and feature classes that are part of your map in your editoparation in order to make any changes part of an undo/redo operation.

2) You should not open a new database connection each time you delete a record. The database connection should be established once in your session for various reasons.

If you really can't include the standalone table in your TOC you should still adhere to my 2. point above and try to create the database connection only once and then use Table.DeleteRows (QueryFilter) (DeleteRows Method—ArcGIS Pro) to delete the related rows.