3

I have a feature class. On the basis of some calculation, I want to create a new field in that table and set value of that field. To do so, my algorithm is:

void UpdateFeatureClass(IFeatureClass featureClass, List<Edge> edges)
{
    CreateField(featureClass);
    UpdateDictionary(featureClass);
    UpdateFieldValue(edges);
}

To add a field I use following code snippet:

private void CreateField(IFeatureClass featureClass)
{
    IFields oldFields = featureClass.Fields;
    IFieldsEdit fieldsEdit = (IFieldsEdit)oldFields;

    IField field = new FieldClass();
    var fieldEdit = (IFieldEdit)field;
    fieldEdit.Name_2 = "Value";
    fieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
    fieldsEdit.AddField(field);
}

Update dictionary basically creates a dictionary with all features of the feature class. The key of the dictionary is feature's OID and value of the dictionary is the feature. After that I am trying to update features with value in the value field. The code snippet is:

private void UpdateFieldValue(List<Edge> edges)
{
    int fieldIndex = dictionary[0].Fields.FindField("Value");
    if (fieldIndex != -1)
    {
        foreach (Edge edge in edges)
        {
            var feature = _dictionary[edge.PolylineEdge.OID];
            feature.set_Value(fieldIndex, edge.Value);
            feature.Store();
        }
    }
}

Everything works fine for me except the feature.Store() command. Whenever this line executes, 'System.Runtime.InteropServices.COMException' exception occurs. From my perspective, if there is any problem with set value, the error should occur in that statement. I couldn't find out any pointer why the store command creates the error. Can anyone please help me to find why the error is occurring?

EDIT : I tried to store value in different fields of the feature and succeeded. Only updating the value of the newly created field, gives the exception.

  • Error message: "Error encoding INFO item during save"
  • Error code: (-2147220133)

EDIT : I think the problem is the newly created field is not permanent. after adding the field, I go through the feature class and the newly created field is here. But whenever I close the ArcMap and open a new ArcMap, I find that the newly added field is vanished. So, I think the problem is the change is not permanent. So, My question is how to create a field in a already created feature class permanently?

Thanks

6
  • Is your feature class a shapefile or a geodatabase feature class?
    – artwork21
    Commented Apr 9, 2013 at 11:11
  • @artwork21: It is a shapefile
    – Emi
    Commented Apr 9, 2013 at 11:16
  • To debug it I would first hard-code the feature.set_Value statement to always set a specific value to (maybe) a specific field and take it from there.
    – mapoholic
    Commented Apr 9, 2013 at 14:35
  • @mapoholic: I tried to set value in different fields and store features, there was no exceptions. But when I set value in the newly created field and store the feature, the exception occurred
    – Emi
    Commented Apr 10, 2013 at 4:12
  • is edge.Value an integer?
    – vinayan
    Commented Apr 10, 2013 at 5:27

2 Answers 2

3

To create a new field I think you need to have a schema lock first (ISchemaLock)

From the example in here:

public void AddFieldToFeatureClass(IFeatureClass featureClass, IField field)
{
    ISchemaLock schemaLock = (ISchemaLock)featureClass;

    try
    {
        // A try block is necessary, as an exclusive lock might not be available.
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);

        // Add the field.
        featureClass.AddField(field);
    }
    catch (Exception exc)
    {
        // Handle appropriately for your application.
        Console.WriteLine(exc.Message);
    }
    finally
    {
        // Set the lock to shared, whether or not an error occurred.
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
    }
}
2

From the documentation on IFieldsEdit:

The IFieldsEdit interface is used when creating a fields collection. You cannot use it to insert or delete a field from a fields collection belonging to an existing table. To add a field to an existing object class, use the IClass::AddField method. To remove a field from an existing object class, use the IClass::DeleteField method.

So either use IClass.AddField or the geoprocessor to do it.

For better performance consider using IGeoDatabaseBridge.GetFeatures which returns a cursor given a set of Object IDs.

4
  • Thanks for your contribution. Actually I already tried IClass.AddField method and succeeded.
    – Emi
    Commented Apr 11, 2013 at 4:10
  • I am using var featureCursor = featureClass.Search(null, false); for getting all features. Does IGeoDatabaseBridge.GetFeatures better perform than that?
    – Emi
    Commented Apr 11, 2013 at 5:50
  • 1
    GetFeatures is used when you already have a set of Object IDs. Since you are using a non-recycling cursor to save a reference to each feature, you might get better performance if you were to instead use a recycling cursor to save each Object ID instead of an IFeature, and subsequently use GetFeatures with the ObjectIDs you need to update the features. I am only guessing, but I think this would be more efficient.
    – blah238
    Commented Apr 11, 2013 at 11:19
  • IClass.AddField method adds field in a shape file perfectly, but whenever I am working with any geodatabase feature class, IClass.AddField method gives error: Cannot acquire a schema lock because of an existing lock.
    – Emi
    Commented Jul 21, 2013 at 5:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.