Yes you can read (and probably write) Spatial Data with Entity Framework

After thinking about the issue with EF4 still not supporting spatial data, I emailed spatial data wizard, Jason Follas, and asked him his thoughts. He’s not too familiar with EF but said if EF supported blob types then you could just use the Microsoft.SqlServer.SqlGeometry type to read in the blob data from a stream.

I emailed back and said, well then if there’s a way to cast the geometry data, then we can create a view to provide the spatial data and stored procs to update it.

Then he and I both ended up with the same solution.

He created a table from scratch. I downloaded a sample table from CodePlex that has US Census Data containing in a SQL Server 2008 table that contains a geometry column.

Then we both came up with the correct cast (I floundered but let the error messages and some googling (oh wait, I think I was Binging :)) help me figure out what I was supposed to cast to) and the following view was born.

SELECT     StateID, StateName, CONVERT([varbinary](MAX), geom, 0) AS Geo
FROM         dbo.State

Well, it was born twice. One twin in Vermont, the other in Ohio. 🙂

EF’s EDM Wizard happily reads in the view:

state

And has no problem executing queries and materializing the object:

      using (var context=new myEntities())
      {
        var stateData = context.States.First();
        var geoProperty = stateData.geomBlob();
      }

Next is to take geoProperty and stream it into a SqlGeometry type (thanks again to Jason for pointing this out), and you are good to go.

If you want to do updates, then you’ll need some stored procs that you can pass the binary data into which will convert (on the server side) back into the geometry type. This is theoretical on my part. You should absolutely be able to do this. I just haven’t done it myself. Hopefully someone will try it out and let me know that it works! 🙂

And there’s no reason this shouldn’t work in both EF1 and EF4.

Querying is a different story. LINQ does not support querying the spatial data nor does ESQL. But EF supports query stored procedures if that can help. I really don’t know much about working with the spatial types so this perhaps Jason and I can continue to put our heads (and expertise) together on this.

I’m not working through part where we read in the SqlGeometry type because I don’t have the correct assembly on my computer. Jason has a blog post about getting the correct assembly for using the SqlGeometry type directly in .NET.

So, while the EDM doesn’t support the spatial types directly, it is still possible to work with them when using EF without too much inconvenience.

  Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!  

9 thoughts on “Yes you can read (and probably write) Spatial Data with Entity Framework

  1. In case Julie doesn’t post it, converting a byte[] array (the geomBlob) to an actual SqlGeometry (or SqlGeography) type is pretty straightforward:

    // geoProperty should be a byte[]

    var sqlGeom = new Microsoft.SqlServer.Types.SqlGeometry();

    using (var stream = new System.IO.MemoryStream(geoProperty))

    {

    using (var rdr = new System.IO.BinaryReader(stream))

    {

    sqlGeom.Read(rdr);

    }

    }

  2. The query issues are a particularly painful point for me, unfortunately. I’m currently working on a pretty substantial side project and, despite my love for the EF4, was forced to go with NHibernate for its NHibernate.Spatial functionality.

    Reading and writing SQLGeography is all well and good, but if I have to pull all of my data into my application and run a local LINQ to Objects query on it, I lose the benefit of the spatial indices in SQL Server and I’m stuck querying over a few million records, one by one.

  3. I am doing the same thing with Oracle Spatial. I have not tried an insert yet but update works fine. What I did was create an updatable view that converts from SDO_GEOMETRY to OGC WKB and then EF maps as BLOB in the store model and Binary in the conceptual model. I attempted the property wrapper path as described in a blog on devArts forum. While I succeeded in building the conversion from binary to ERSI geometry within EF I could not serve that type up through ADO.Net Data Service and so moved that conversion down to the client. I am using a modified geometry converter from SharpMap to convert from WKB to ESRI Silverlight Geometry type. Geometry manipulation is done against the ESRI geometry type in Silverlight. We do not need to query spatially through the data service or EF at this point. Read only access to the data for display and record selection through AGS is much faster than through the ADO.net Data Service with or without a spatial query, measured in seconds in AGS compared to minutes. To edit an existing geometry we find it through AGS and then query an entity instance up through the data service by primary key, editting one record at a time. Yes, it is a bit convoluted but it fits within the sideboards of the project I am working on.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.