Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use strong spatial types option in model designer locked?

I'm working on a model first EF6 model in model first approach.

EF exposes more than DBGeometry and DBGeography and allows me to select specific subtypes when designing the model (like GeographyPoint).

However my generated classes are still simply DBGeography even when i select a more specific subtype.

I notice a property on the model that is named "Use Strong Spatial Types" but it is set to false by default and seems locked (greyed out, no dropdown list, can't type). This seems to imply a support for generating stronger typed classes (that would have GeographyPoint instead of DBGeography in the generated class for example)

Any idea what could be causing this? This sounds like a helpful feature.

I'm targeting SQL Server Express 2012, if this is an issue i can switch to another edition as i'm not doing anything versions specific.

UPDATE : see image link if you're not sure you understand what i'm refering to!

https://www.dropbox.com/s/lzgsoi60whuicy0/EF%20Spacial%20Strong.png?dl=0

enter image description here

like image 404
Ronan Thibaudau Avatar asked Sep 11 '14 23:09

Ronan Thibaudau


2 Answers

Written as regards to Entity Framework v6.1.1 implementation.

If you are looking for a specific classes like GeographyPoint instead of DBGeography for your property then there's no such in Entity Framework implementation.

All geography-related stuff for Entity Framework is concentrated in one System.Data.Entity.Spatial.DBGeography class. Instance of such class can act differently based on actual data.

For example, if you work with a Point, you can access Elevation, Longitude and Latitude properties. If it's actually a collection, you can access ElementCount property.

And in your queries you can use DbGeography methods (i.e. Distance()) to perform type-specific queries like:

var myLocation = DbGeography.FromText("POINT(40.7127, 74.0059)");
var results = from p in Points
              orderby p.Distance(myLocation)
              select p;

Actually, I don't see a 'Use strong spatial types' property running VS 2013.3, EF Power Tools Beta 4.

UPDATE

Found it under actual data model properties. Well, it's more of a question to developers of EF, but if you look at the source code of EFEntityModelDescriptor (component that describes all those extension menu items), there are two properties that responsible for Use Strong Spatial Types menu item:

  1. UseStrongSpatialTypes which returns true by-default or calls GetUseStrongSpatialTypesFeatureState:

    internal static FeatureState GetUseStrongSpatialTypesFeatureState(Version schemaVersion)
    {
        Debug.Assert(EntityFrameworkVersion.IsValidVersion(schemaVersion), "Invalid schema version.");
    
        return schemaVersion > EntityFrameworkVersion.Version2
                   ? FeatureState.VisibleAndEnabled
                   : FeatureState.VisibleButDisabled;
    }
    

As you can see, all EF versions above 2 should return FeatureState.VisibleAndEnabled. Current implementation is EntityFrameworkVersion.Version3, but still menu item is disabled and still its value is false. We see false in the designer because of the annotation specified in Conceptual Model in your edmx-file that explicitly set it to false:

    <!-- CSDL content -->
<edmx:ConceptualModels>
  <Schema xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" 
          annotation:UseStrongSpatialTypes="false">
  </Schema>
</edmx:ConceptualModels>

This is set to false on the generation phase in EdmXmlSchemaWriter

        if (_version == XmlConstants.EdmVersionForV3)
        {
            _xmlWriter.WriteAttributeString(
                AnnotationNamespacePrefix,
                XmlConstants.UseStrongSpatialTypes, 
                XmlConstants.AnnotationNamespace,
                XmlConstants.False);
        }

But if EF version is 3 and FeatureState is VisibleAndEnabled why is the menu item is disabled? That leads us to the next property:

  1. IsReadOnlyUseStrongSpatialTypes with the following implementation (true always):

    internal bool IsReadOnlyUseStrongSpatialTypes()
    {
        // TODO: when runtime support for the other (true) setting of this attribute is available replace the "return true" below by the commented line below it
        return true;
        // return (!EdmFeatureManager.GetUseStrongSpatialTypesFeatureState(TypedEFElement.Artifact.SchemaVersion));
    }
    

As you can see, it always returns true and from a TODO comment we can guess that there's no support for this currently. Unfortunately, there's no source code available for older versions of EntityDesign project, so it's hard to track why exactly this was changed.

As Pawel mentioned in this comment, EF team wanted to adopt some existing spatial library (without having to implement and maintain it), but there was no options, so they implemented simpler DbGeography and DbGeometry classes until other options become available.

Probably, since then IsReadOnlyUseStrongSpatialTypes property was changed to always return true, so that Use Strong Spatial Types menu item is greyed-out in the designer and a Description note was added about DbGeography and DbGeometry types used.

SUMMARY

Just to summarize my answer - it's disabled because it is not applicable for Entity Framework v5.0 and onwards (and corresponding versions of Visual Studio) - implementation has changed.

like image 146
t3z Avatar answered Oct 22 '22 20:10

t3z


The reason why the "Use Strong Spatial Types" option is grayed out in the EF designer is that false is the only option allowed by the EF runtime. Now, obviously the question is - why is this the only value supported by the runtime. You can find the answer in the code - if you look at the TypeUsageBuilder class you will find the following comment around line 200:

// Forward compat FUTURE SYSTEM.SPATIAL
// for now we treat all Geographic types the same, and likewise for geometry.
// to allow us to later introduce the full heirarchy without breaking back compat
// we require spatial types to have the IsStrict facet with a false value.    
// Set this facet to false if the schema has the UseStrongSpatialTypes attribute with the a false.

From what I remember as a member of the EF team at that time we (as the EF team) did not want to be in the business of creating and maintaining our own spatial library as this is not what an ORM team should focus on. There wasn't also any spatial library at that time we could adopt so we decided to go with something simple that would work (read the DbGeometry and DbGeography types). I think the hope was that we would be able to use this spatial library which was being started developed at that time but it never happened. Also note that the EDM type system (used in CSDL) contains the notion of spatial subtypes (ln. 183) but when they need to be translated to a Clr type the DbGeometry or DbGeography type will be returned (see: PrimitiveType ln. 181)

like image 2
Pawel Avatar answered Oct 22 '22 20:10

Pawel