Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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

share|improve this question
    
Is your feature class a shapefile or a geodatabase feature class? –  artwork21 Apr 9 '13 at 11:11
    
@artwork21: It is a shapefile –  Emi Apr 9 '13 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 Apr 9 '13 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 Apr 10 '13 at 4:12
    
is edge.Value an integer? –  vinayan Apr 10 '13 at 5:27

2 Answers 2

up vote 2 down vote accepted

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.

share|improve this answer
    
Thanks for your contribution. Actually I already tried IClass.AddField method and succeeded. –  Emi Apr 11 '13 at 4:10
    
I am using var featureCursor = featureClass.Search(null, false); for getting all features. Does IGeoDatabaseBridge.GetFeatures better perform than that? –  Emi Apr 11 '13 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 Apr 11 '13 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 Jul 21 '13 at 5:20

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);
    }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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