Kemal Tezer Dilsiz
Kemal Tezer Dilsiz

Reputation: 4009

System.Data.Entity.Spatial replacement in ASP.NET Core

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)

Upvotes: 24

Views: 20263

Answers (7)

Ahmed Suror
Ahmed Suror

Reputation: 500

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...

Upvotes: 0

Adi
Adi

Reputation: 139

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

Upvotes: 0

Hatef.
Hatef.

Reputation: 544

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!

Upvotes: 19

Yanga
Yanga

Reputation: 3012

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/

Upvotes: 1

Johan
Johan

Reputation: 1515

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()));
        }

Upvotes: 0

Hades
Hades

Reputation: 885

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)

Upvotes: 1

Sai Puli
Sai Puli

Reputation: 971

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

Upvotes: 0

Related Questions