質問

I have an Odata service which exposes an EF6 code first model. Some of these entities include DbGeography fields. I can GET these field, despite the DbGeography fields having quite an ugly serialized format, but I cannot figure out how to POST or PUT an entity to the service. The DbGeography type seems to struggle with deserialization.

Can anyone provide an example or link for how to do this?

役に立ちましたか?

解決

I've had this problem too. Its a bug apparently.

Either two choices here - drop down to EF5 for the old System.Data.Entity.DbGeography (rather than System.Data.Entity.Spatial.DbGeography), or wait until they patch it.

Edit: Its been a long time, and so far the only hack I've come up with is this as a way to write to the properties and hide the ugly serialised format (however still cannot query against it.

    private bool hasSetLongitude = false;
    private bool hasSetLatitiude = false;
    private double? longitude = null;
    private double? latitiude = null;

    /// <summary>
    /// Get or set the coordinates.
    /// </summary>
    [Column("engi_coord"), Required]
    public DbGeography Coordinates { get; set; }

    /// <summary>
    /// Get or set the lang coordinates.
    /// </summary>
    [Column("engi_lng"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public double? Longitude
    {
        get 
        { 
            return this.Coordinates != null ? this.Coordinates.Longitude : (double?)null; 
        }
        set 
        {
            this.longitude = value;
            this.hasSetLongitude = true;
            if (this.hasSetLongitude)
            {
                if (this.longitude.HasValue &&
                    this.latitiude.HasValue)
                {
                    this.Coordinates = DbGeography.PointFromText(string.Format("POINT({0} {1})", this.longitude.Value, this.latitiude.Value), 4326);
                }
                else
                {
                    this.Coordinates = null;
                }
            }
        }
    }

    /// <summary>
    /// Get or set the lat coordinates.
    /// </summary>
    [Column("engi_lat"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public double? Latitude
    {
        get 
        { 
            return this.Coordinates != null ? this.Coordinates.Latitude : (double?)null; 
        }
        set 
        {
            this.latitiude = value;
            this.hasSetLatitiude = true;
            if (this.hasSetLatitiude)
            {
                if (this.longitude.HasValue &&
                    this.latitiude.HasValue)
                {
                    this.Coordinates = DbGeography.PointFromText(string.Format("POINT({0} {1})", this.longitude.Value, this.latitiude.Value), 4326);
                }
                else
                {
                    this.Coordinates = null;
                }
            }
        }
    }

Migrate to add the computed columns:

        this.Sql("ALTER TABLE dbo.engi_engineer ADD engi_lng AS engi_coord.Long");
        this.Sql("ALTER TABLE dbo.engi_engineer ADD engi_lat AS engi_coord.Lat");

Now ignore the coordinates property from API:

        this.EntityType.Ignore(p => p.Coordinates);

他のヒント

Well it has been over a year now and it doesn't look like this is getting fixed anytime soon. Especially with EF7 coming out very soon.

So, I would like to approach this another way.
What if the DbGeography type was not exposed as a property on the class and instead we expose a Latitude and Longitude property that are not mapped and then on their GET / SET we update the hidden DbGeography property?

I have tried this but have been unsuccessful with EF.
What you can do is inside the POST / PUT controller calls is use a stored procedure or SQL text to update the data.

If I find out how to get this to work with EF I will post here.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top