System.Data.Entity.Spatial replacement in ASP.NET Core
Asked Answered
H

7

23

I am trying to migrate a webform from ASP.NET MVC to ASP.NET Core MVC. Currently I am trying to find a way to replace:

using System.Data.Entity.Spatial;

since it is not currently available in .NET Core or I may have not been able to find it.

Is there a way of including this package? Maybe through a NuGet package?

Ps. I read Microsoft guideline briefly but could not find anything related to it. For anyone who may be in a similar situation, the guide is here: https://docs.asp.net/en/latest/migration/mvc.html

(Sorry if I couldn't write a good question, I am trying to get used to the system here)

Herrod answered 2/8, 2016 at 18:45 Comment(1)
P
19

Edit

This feature is new in EF Core 2.2

Spatial Data now added to EF Core 2.2 (see documentation)


Before EF Core 2.2 versions use this:

Now you can use Microsoft.Spatial for geography and geometry spatial operations.

ofc , EntityframeworkCore does not support spatial, so you can not create a field with geography data type in codefirst, I suggest you to do this with pure SQL commends until EntityframeworkCore supports spatial in Q2 2017 (See this). If you don't know how I will tell you.

  1. First of all you need to add a field with geography data type, so you need to run this commend in one of migrations up classes :

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql("ALTER TABLE [dbo].[Cities] ADD [Location] geography");
    }
    
  2. if you are using UnitOfWork you can update Location field after you inserted a record like this :

        try
        {
            City city = new City
            {
                Title = creator.Title
            };
    
            _cities.Add(city);
    
            _uow.ExecuteSqlCommand("UPDATE Cities SET Location = geography::STPointFromText('POINT(' + CAST({0} AS VARCHAR(20)) + ' ' + CAST({1} AS VARCHAR(20)) + ')', 4326) WHERE(ID = {2})", city.Longitude, city.Latitude, city.ID);
    
            return RedirectToAction("Index");
        }
        catch
        {
            return View(creator);
        }
    
  3. And now if you want to find nearby cities, you can use this commend :

        var cities = _uow.Set<City>()
            .FromSql(@"DECLARE @g geography = geography::STPointFromText('POINT(' + CAST({0} AS VARCHAR(20)) + ' ' + CAST({1} AS VARCHAR(20)) + ')', 4326);
                       Select ID, Address, CreationDate, CreationDateInPersian, CreationDateStandard, CreatorRealName, CreatorUserID, ExLanguageID, IsActive, IsDeleted, Latitude, Longitude, ModifierRealName, ModifierUserID, ModifyDate, ModifyDateInPersian, ModifyDateStandard, PhoneNumbers, Summary, TimeStamp, Title, Image from Cities
                       ORDER BY Location.STDistance(@g) DESC;",
                       35.738083, 51.591263)
                       .Select(x => new AllRecordsViewModel
                       {
                           ID = x.ID,
                           Title = x.Title
                       })
            .ToList();
    
        return View(cities);
    

// result for nearest cities :

1.Tehran
2.Ankara
3.Paris
4.Washington DC

Remember! you should select all of records except that field with geography data type!

Pietro answered 12/3, 2017 at 11:11 Comment(2)
Instead of Microsoft.Spatial, you may want to use the System.Spatial package, also from Microsoft.Ymir
hi @AuriRahimzadeh could you please provide a doc link? I found it, but the doc is very general. thanksArnulfoarny
E
1

Spatial data isn't supported yet by Entity Framework Core.

Spatial is not planned for 2.0 and we haven’t finished planning for the version after. It might be a good idea to post more details about what you would like to have in spatial support at https://github.com/aspnet/EntityFramework/issues/1100, e.g. do you use specific spatial functions or do you need rich spatial types with all kinds of spatial functionality, would you use this only with a specific database or do you need to write the same code against multiple databases? Etc.

(Source: MSDN .NET Blog)

I have made a temporary workaround to include Geography column and use it in EF Core 1.0.0 and above. It's not perfect, but it will do for now. (Similar to Hatef’s answer apparently, wow great minds think alike I guess.)

See the accepted answer on: Entity Framework Core: Type Udt is not supported on this platform. (Spatial Data - Geography)

Erewhile answered 6/7, 2017 at 13:0 Comment(2)
Found this comment on issue 1100 leading me to docs which tells you which NetTopologySuite NuGet package to download and how to use itThwart
@Thwart Oh nice to know there's finally an update for that. Cool :)Erewhile
P
1

With Entity Framework Core 2.2 you can use NetTopologySuite spatial library.

You can then do a query like:

var nearestCity = db.Cities
    .OrderBy(c => c.Location.Distance(currentLocation))
    .FirstOrDefault();

A complete exemple is available here : https://www.markopapic.com/finding-nearby-users-using-ef-core-spatial-data/

Pimpernel answered 19/12, 2018 at 10:41 Comment(0)
W
0

It is purely because Entity Framework 7 doesn't support Spatial stuff. Yet. You can follow the github issue related to it here. https://github.com/aspnet/EntityFramework/issues/1100

Wailoo answered 2/8, 2016 at 19:7 Comment(4)
I read that issue yesterday. I guess then I need to find an alternative way of implementing the features? Or should I try to stick with the previous version if my application is too dependent on Spatial stuff?Herrod
If the application is heavily dependent on Geography stuff, I'd recommend staying with EF 6 for now. At least until some pull requests show up under that github issue.Wailoo
Thanks! Can I ask about few more packages? System.Configuration and System.Web.Mvc, I am using ConfigurationManager from System.Configuration and some View classes(example, ViewEngineResult, ViewContext) from System.Web.Mvc. Do you know where I could replace these?Herrod
Configuration management has changed quite a bit and moved to ConfigurationBuilder in core. docs.asp.net/en/latest/fundamentals/configuration.html. Not sure about ViewEngineResult, I guess it is moved to Microsoft.AspNetCore.Mvc namespace. docs.asp.net/projects/api/en/latest/autoapi/Microsoft/…Wailoo
S
0

EDIT:

Here are the official docs for NetTopologySuite with EF Core (Thanks to ono2012):

Spatial Data - EF Core


Original post:

Update 2018-12-10

Later versions of Entityframework Core now supports spatial data using the NetTopologySuite (see documentation). I think it's supported since 2.1 but I'd recommend 2.2+ due to a bug in 2.1 where coordinates are inverted when saved to database.

Your project needs to target .NET Core 2.1+ (preferably 2.2+).

I managed to get it to work with SQL Server 2016 by adding the following nuget packages:

Microsoft.AspNetCore.All
Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite

To use it in your DBContext you need to add the following options in your startup.cs:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<PMSdp3_Context>(o => 
                     o.UseSqlServer(connString, opt => opt.UseNetTopologySuite()));
        }
Sybyl answered 10/12, 2018 at 15:44 Comment(1)
Found this comment on issue 1100 leading me to docs which tells you which NetTopologySuite NuGet package to download and how to use itThwart
G
0

I used using Microsoft.Spatial in ASP.NET Core project as a replacement for using System.Data.Entity.Spatial and it worked.

Geniagenial answered 17/2, 2022 at 6:8 Comment(0)
B
0

According to this Microsoft Learn post

In order to use spatial data with EF Core, you need to install the appropriate supporting NuGet package. Which package you need to install depends on the provider you're using.

supporting NuGet packages are NetTopologySuite extensions to database providers like MSSQL, MySQL, etc...

Blackfish answered 11/8, 2023 at 23:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.