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 am trying to use the following code to select the features that have the attribute values that I pass in. The performance is really slow when it comes to a lot of values e.g >16k values to match features.

Is there something I'm missing or a better way of doing this?

// Assuming values.Any() is true:

var featureSelection = (layer as IFeatureSelection);

var whereClause = new StringBuilder();
var count = 0;
while (true)
{
    var values = valuesToSelect.Skip(count*1000).Take(1000).ToList();
    if (!values.Any()) break;
    var thousandsClause = new StringBuilder();
    foreach (var value in values)
    {
        thousandsClause.Append(",");
        thousandsClause.Append(value);
    }
    thousandsClause.Remove(0, 1);
    thousandsClause.Insert(0, fieldName + " IN (");
    thousandsClause.Append(")");
    whereClause.Append(" OR " + thousandsClause);

    count++;
}
whereClause.Remove(0, 4);
IQueryFilter queryFilter = new QueryFilter();
queryFilter.WhereClause = whereClause.ToString();

featureSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
featureSelection.SelectionChanged();

Sample WHERE IN clauses:

761 values to select

122,072 values to select

Edit--

So far with recommendations from some of the comments, I've improved the code and the results are faster but still not desirable. Here is the code I've begun trying using the same WHERE IN clause:

IQueryFilter queryFilter = new QueryFilter();
queryFilter.WhereClause = whereClause.ToString();
queryFilter.SubFields = "OBJECTID";

var featureLayer = layer as IFeatureLayer2;
if (featureLayer == null) continue;

IFeatureClass featureClass = featureLayer.FeatureClass;
var dataset = (IDataset) featureClass;
IWorkspace workSpace = dataset.Workspace;
ISelectionSet selectionSet = featureClass
.Select(queryFilter, esriSelectionType.esriSelectionTypeHybrid,esriSelectionOption.esriSelectionOptionNormal,workSpace);

var featureSelection = layer as IFeatureSelection;
if (featureSelection != null)
{
    featureSelection.SelectionSet = selectionSet;
    featureSelection.SelectionChanged();
}
share|improve this question
    
Can you add an example of the whereClause that is built with your code to your question? –  awesomo Jan 31 '13 at 18:08
    
I've edited the question with sample generated where in clauses @awesomo –  leon Jan 31 '13 at 18:22
    
Those links aren't working for me –  awesomo Jan 31 '13 at 18:27
1  
If you're always querying objectid, it would be much faster to just use ISelectionSet.AddList. –  Kirk Kuykendall Jan 31 '13 at 18:38
4  
In cases where you aren't querying oids, I think it would be easier to scan the featureclass to find the OIDs whose attribute appears in your list, then use the AddList method. You can speed up the scan by using a queryfilter with a subfield that is your field of interest and specifying recycling=true when you open the cursor. Also having the values of interest in a dictionary where you can call KeyExists might be faster than having them in a list and calling the Contains. –  Kirk Kuykendall Jan 31 '13 at 19:51

1 Answer 1

I see you're building a massive where clause which is causing your SQL to get testy. I would try to select each case in turn and then add to the selection set for each new case:

    ISelectionSet FinalSet = FeatureClass.Select(
    null,
    esriSelectionType.esriSelectionTypeHybrid,
    esriSelectionOption.esriSelectionOptionEmpty,
    workSpace);

ISelectionSet Recycle;
IQueryFilter pQF = new QueryFilterClass();
while (true) 
{ // include here getting the value for each selection

    pQF.WhereClause = fieldName + " = " + value;
    Recycle = FeatureClass.Select(
        pQF,
        esriSelectionType.esriSelectionTypeHybrid,
        esriSelectionOption.esriSelectionOptionNormal,
        workSpace);
    FinalSet.Combine(Recycle,esriSetOperation.esriSetUnion,FinalSet);
}

This will do multiple small selections and accumulate them into the FinalSet then you can do your featureslection from the FinalSet.

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.