将几何图形转换为地理图形的实体框架



我正试图通过数据库中的Entity类插入一个Geometry对象,但错误"地理学与几何学不相容";始终返回。我最初收到一个字符串,它传递了几何坐标的X和Y值,并进行了必要的转换以创建Geometry提供的点类型,我不需要进行任何计算,所以Geometry类型是我现在最好使用的类型。我使用以下功能进行转换:

public static Geometry ConvertToGeometry(string coordinatesAux)
{
if(coordinatesAux == null)
throw new NullReferenceException();
NumberFormatInfo formatProvider = new NumberFormatInfo();
formatProvider.NumberGroupSeparator = ".";

var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var currentLocation = geometryFactory.CreatePoint(new Coordinate(
Convert.ToDouble(coordinatesAux.Substring(0, coordinatesAux.IndexOf(",")), formatProvider), 
Convert.ToDouble(coordinatesAux.Substring(coordinatesAux.IndexOf(",") + 1), formatProvider)));

return currentLocation;                                                            
}

我还在Startup.cs中对db进行了必要的修改,以使用NetTopologySuite,但当我试图通过API插入该值时,它会返回最初描述的错误。我不知道问题是我从字符串转换为几何体的方式,还是实体本身将字段识别为地理点。

我试图传递的值是-20.338113、-40.287893,我使用的实体类是:

public class Address : EntityBase<int>
{
public Address(string district, string street, int number, string complement, string zipCode, 
string cityDescription, string stateDescription, Geometry coordinates, int countryId, byte stateId, int cityId)
{
District = district;
Street = street;
Number = number;
Complement = complement;
ZipCode = zipCode;
CityDescription = cityDescription;
StateDescription = stateDescription;
Coordinates = coordinates;
CountryId = countryId;
StateId = stateId;
CityId = cityId;
}
public string District { get; set; }
public string Street { get; set; }
public int Number { get; set; }
public string Complement { get; set; }
public string ZipCode { get; set; }
public string CityDescription { get; set; }
public string StateDescription { get; set; }
public virtual Geometry Coordinates { get; set; }
public int CountryId { get; set; }
public byte StateId { get; set; }
public int CityId { get; set; }
public int? CustomerId { get; set; }
public int? StoreId { get; set; }
public int? ProfessionalId { get; set; }
}

所以,再问一次,是实体框架做了什么,还是我犯了错误?如果需要代码的更多部分,我将编辑要添加的问题。


编辑1

表地址:

CREATE TABLE Address(
Id INT PRIMARY KEY IDENTITY(1, 1),
District VARCHAR(50) NOT NULL, -- Bairro
Street VARCHAR(100) NOT NULL, -- Rua
--Description VARCHAR(100) NOT NULL,
Number INT,
Complement VARCHAR(100),
ZipCode VARCHAR(20) NOT NULL,
CityDescription VARCHAR(100),
StateDescription VARCHAR(100),
Coordinates GEOMETRY,

CountryId INT FOREIGN KEY REFERENCES Country(Id) NOT NULL,
StateId TINYINT FOREIGN KEY REFERENCES State(Id),
CityId INT FOREIGN KEY REFERENCES City(Id),
CustomerId INT FOREIGN KEY REFERENCES Customer(Id),
StoreId INT FOREIGN KEY REFERENCES Store(Id),
ProfessionalId INT FOREIGN KEY REFERENCES Professional(Id),
INDEX IndexAddressCountryId NONCLUSTERED (CountryId),
INDEX IndexAddressStateId NONCLUSTERED (StateId),
INDEX IndexAddressCityId NONCLUSTERED (CityId),
INDEX IndexAddressCustomerId NONCLUSTERED (CustomerId),
INDEX IndexAddressStoreId NONCLUSTERED (StoreId),
INDEX IndexAddressProfessionalId NONCLUSTERED (ProfessionalId)
)

这里有一个工作良好的示例,映射到geometrygeography。你必须看看你在做什么。(顺便说一句,您可能希望geography作为SQL Server中的geometry是一个平面欧几里得空间,不会为您提供准确的距离计算或纬度和经度坐标的直线(。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Common;
using System.Linq;
using System.Security.Cryptography;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using NetTopologySuite.Geometries;

namespace EfCore3Test
{
public class Address : EntityBase<int>
{
public Address() { }
public Address(string district, string street, int number, string complement, string zipCode,
string cityDescription, string stateDescription, Geometry coordinates, int countryId, byte stateId, int cityId)
{
District = district;
Street = street;
Number = number;
Complement = complement;
ZipCode = zipCode;
CityDescription = cityDescription;
StateDescription = stateDescription;
Coordinates = coordinates;
CountryId = countryId;
StateId = stateId;
CityId = cityId;
}
public string District { get; set; }
public string Street { get; set; }
public int Number { get; set; }
public string Complement { get; set; }
public string ZipCode { get; set; }
public string CityDescription { get; set; }
public string StateDescription { get; set; }
//[Column(TypeName ="geometry")]
public virtual Geometry Coordinates { get; set; }
public int CountryId { get; set; }
public byte StateId { get; set; }
public int CityId { get; set; }
public int? CustomerId { get; set; }
public int? StoreId { get; set; }
public int? ProfessionalId { get; set; }
}
public class EntityBase<T>
{
public T Id { get; set; }
}
public class Db : DbContext
{

public Db(): base()
{
}
private static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddFilter((category, level) =>
category == DbLoggerCategory.Database.Command.Name
&& level == LogLevel.Information).AddConsole();
});
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var constr = "Server = localhost; database = efcore3test; integrated security = true";
optionsBuilder.UseLoggerFactory(loggerFactory)
.UseSqlServer(constr, o => o.UseRelationalNulls().UseNetTopologySuite());

base.OnConfiguring(optionsBuilder);
}
public DbSet<Address> Addresses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}


class Program
{

static void Main(string[] args)
{

using (var db = new Db())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
var geometryFactory = NetTopologySuite.NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var currentLocation = geometryFactory.CreatePoint(new NetTopologySuite.Geometries.Coordinate(-122.121512, 47.6739882));
var addr = new Address("a", "a", 1, "a", "00223", "city", "state", currentLocation, 1, 2, 3);
db.Addresses.Add(addr);
db.SaveChanges();
}
}
}
}

最新更新