ThinkGeo.com    |     Documentation    |     Premium Support

ExecuteQuery no longer works with shapefiles

We have many places in our code where we use ExecuteQuery with ShapeFileFeatureLayers. From another post I see that this feature is no longer supported. Is there a recommended workaround? I was thinking If I wanted to accomplish the query i might be able to do so by converting the dbf data to a standard DataSet, but I would prefer not to have to do that.

Thanks!

Steve

Hi Steve,

You’re right that ExecuteQuery was dropped from ShapeFileFeatureLayer. The original implementation read the .dbf companion through System.Data.OleDb with the Microsoft.Jet.OLEDB.4.0 provider, which is for Windows-only and doesn’t exist on .NET Core +, so we removed it during the cross-platform migration from v12.

You can subclass ShapeFileFeatureSource and wire OleDb back in for a Windows-only project, but the deployment story is rough: Jet 4.0 was never built for x64, and the 64-bit alternative (ACE 12.0) needs every end-user machine to have the Microsoft Access Database Engine Redistributable installed at the matching bitness. The only “no-install” path is forcing x86, with the 32-bit address-space ceiling. Most
customers can’t accept that anymore.

So converting the dbf data to a standard DataSet is not a bad idea. Also ThinkGeo.Gdal exposes the .dbf through OGR with its own SQL engine, you can try that as well if you already using gdal in the project.

var layer = new GdalFeatureLayer(@"places.shp", "places");
layer.Open();
DataTable dt = layer.QueryTools.ExecuteQuery("SELECT * FROM places WHERE POP > 50000");

Thanks,
Ben

Hi Steven, we recently solved the 32/64 Bitness issue as well if you decide to go down that path. This was not specific to the ExecuteQuery drop, but a different issue, it should work all the same, though. The way to make it work is the following:

You can read the installed driver bitness from the registry.

Then, write a helper program, which uses 32 or 64 bit driver, depending on what is installed. This program needs to execute in 32 or 64 bit, so you need to bundle both.

Communication is done through named pipes, and we internally convert it to csv before sending, but you can probably get it in any shape you want.

Whether that will work for you I dont know, but we solved a 5 year old ticket this way :slight_smile:

Hi Julian,

Thanks for the suggestion!

Steve

Ben,

Thanks, as always, for your quick reply and detailed explanation.

Steve

Ben,

I tried the following query with the GdalFeatureLayer and nothing was returned and there was no exception thrown. Here is the query:

“SELECT MAX(Age) , MIN(Age), COUNT(Age) FROM BC_Mch”

Is there something wrong with the syntax?

Thanks!

Steve

Hi Steven,

Your SQL syntax is fine, the empty result was actually a bug on our side in GdalFeatureSource, not your query.

It’s fixed in ThinkGeo.Gdal 15.0.0-beta037 (just on NuGet):


var layer = new GdalFeatureLayer("BC_Mch.shp");
layer.Open();

DataTable dt = layer.QueryTools.ExecuteQuery(
    "SELECT MAX(Age) AS MaxAge, MIN(Age) AS MinAge, COUNT(Age) AS Total FROM BC_Mch");
// dt.Rows[0]["MaxAge"], etc. — actual numeric values

// ExecuteScalar over aggregates also works and returns a native scalar:
long count = (long)layer.QueryTools.ExecuteScalar("SELECT COUNT(*) FROM BC_Mch");

''

Give beta037 a try and let me know if it works for you.

Thanks,
Ben

Ben,

Works fine in the beta. Do you know how soon this will be in a production version?

Thanks!

Steve

Should be around late this month/early next month.