5

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();
}
15
  • Can you add an example of the whereClause that is built with your code to your question?
    – awesomo
    Jan 31, 2013 at 18:08
  • I've edited the question with sample generated where in clauses @awesomo
    – leon
    Jan 31, 2013 at 18:22
  • Those links aren't working for me
    – awesomo
    Jan 31, 2013 at 18:27
  • 1
    If you're always querying objectid, it would be much faster to just use ISelectionSet.AddList. Jan 31, 2013 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. Jan 31, 2013 at 19:51

1 Answer 1

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.

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.