Uzamsal Veriler
Uzamsal veriler fiziksel konumu ve nesnelerin şeklini temsil eder. Birçok veritabanı, diğer verilerle birlikte dizine alınabilmesi ve sorgulanabilmesi için bu tür veriler için destek sağlar. Yaygın senaryolar, belirli bir konumdan belirli bir mesafedeki nesneleri sorgulamayı veya kenarlığı belirli bir konumu içeren nesneyi seçmeyi içerir. EF Core, NetTopologySuite uzamsal kitaplığını kullanarak uzamsal veri türlerine eşlemeyi destekler.
Yükleme
EF Core ile uzamsal verileri kullanmak için uygun destekleyici NuGet paketini yüklemeniz gerekir. Yüklemeniz gereken paket, kullandığınız sağlayıcıya bağlıdır.
EF Core Sağlayıcısı | Spatial NuGet Paketi |
---|---|
Microsoft.EntityFrameworkCore.SqlServer | Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite |
Microsoft.EntityFrameworkCore.Sqlite | Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite |
Microsoft.EntityFrameworkCore.InMemory | NetTopologySuite |
Npgsql.EntityFrameworkCore.PostgreSQL | Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite |
Pomelo.EntityFrameworkCore.MySql | Pomelo.EntityFrameworkCore.MySql.NetTopologySuite |
Devart.Data.MySql.EFCore | Devart.Data.MySql.EFCore.NetTopologySuite |
Devart.Data.Oracle.EFCore | Devart.Data.Oracle.EFCore.NetTopologySuite |
Devart.Data.PostgreSql.EFCore | Devart.Data.PostgreSql.EFCore.NetTopologySuite |
Devart.Data.SQLite.EFCore | Devart.Data.SQLite.EFCore.NetTopologySuite |
Teradata.EntityFrameworkCore | Teradata.EntityFrameworkCore.NetTopologySuite |
NetTopologySuite
NetTopologySuite (NTS), .NET için bir uzamsal kitaplıktır. EF Core, modelinizdeki NTS türlerini kullanarak veritabanındaki uzamsal veri türlerine eşlemeyi etkinleştirir.
NTS aracılığıyla uzamsal türlere eşlemeyi etkinleştirmek için sağlayıcının DbContext seçenekleri oluşturucusunun UseNetTopologySuite yöntemini çağırın. Örneğin, SQL Server ile bunu şöyle adlandırabilirsiniz.
options.UseSqlServer(
@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters;ConnectRetryCount=0",
x => x.UseNetTopologySuite());
Birkaç uzamsal veri türü vardır. Kullandığınız tür, izin vermek istediğiniz şekil türlerine bağlıdır. Burada, modelinizdeki özellikler için kullanabileceğiniz NTS türlerinin hiyerarşisi yer alır. Ad alanı içinde NetTopologySuite.Geometries
bulunurlar.
- Geometri
- Nokta
- Linestring
- Poligon
- Geometrycollection
- Çoklu
- Multilinestring
- Multipolygon
Uyarı
CircularString, CompoundCurve ve CurePolygon NTS tarafından desteklenmez.
Temel Geometri türü kullanıldığında, her tür şeklin özelliği tarafından belirtilmesine olanak tanır.
Boylam ve Enlem
NTS'deki koordinatlar X ve Y değerleri bakımındandır. Boylam ve enlemi temsil etmek için boylam için X, enlem için Y kullanın. Bunun normalde bu değerleri gördüğünüz biçimden latitude, longitude
geriye dönük olduğunu unutmayın.
Veri Sorgulama
Aşağıdaki varlık sınıfları, Wide World Importers örnek veritabanındaki tablolarla eşlemek için kullanılabilir.
[Table("Cities", Schema = "Application")]
public class City
{
public int CityID { get; set; }
public string CityName { get; set; }
public Point Location { get; set; }
}
[Table("Countries", Schema = "Application")]
public class Country
{
public int CountryID { get; set; }
public string CountryName { get; set; }
// Database includes both Polygon and MultiPolygon values
public Geometry Border { get; set; }
}
LINQ'de, veritabanı işlevleri olarak kullanılabilen NTS yöntemleri ve özellikleri SQL'e çevrilir. Örneğin, Distance ve Contains yöntemleri aşağıdaki sorgularda çevrilir. Hangi yöntemlerin desteklendiğine ilişkin sağlayıcınızın belgelerine bakın.
// Find the nearest city
var nearestCity = db.Cities
.OrderBy(c => c.Location.Distance(currentLocation))
.FirstOrDefault();
// Find the containing country
var currentCountry = db.Countries
.FirstOrDefault(c => c.Border.Contains(currentLocation));
Tersine mühendislik
Uzamsal NuGet paketleri, uzamsal özelliklere sahip tersine mühendislik modellerini de etkinleştirir, ancak veya dotnet ef dbcontext scaffold
çalıştırmadan Scaffold-DbContext
önce paketi yüklemeniz gerekir. Bunu yapmazsanız, sütunlar için tür eşlemelerini bulmama konusunda uyarılar alırsınız ve sütunlar atlanır.
İstemci işlemleri sırasında SRID Yoksayıldı
NTS, işlemler sırasında SRID değerlerini yoksayar. Planar koordinat sistemi olduğunu varsayar. Bu, koordinatları boylam ve enlem açısından belirtirseniz uzaklık, uzunluk ve alan gibi istemci tarafından değerlendirilen bazı değerlerin metre cinsinden değil derece cinsinden olacağı anlamına gelir. Daha anlamlı değerler için öncelikle ProjNet (GeoAPI için) gibi bir kitaplık kullanarak koordinatları başka bir koordinat sistemine yansıtmanız gerekir.
Dekont
ProjNet4GeoAPI adlı eski paketi değil, daha yeni ProjNet NuGet paketini kullanın.
BIR işlem SQL aracılığıyla EF Core tarafından sunucu tarafından değerlendirilirse, sonucun birimi veritabanı tarafından belirlenir.
Burada, iki şehir arasındaki mesafeyi hesaplamak için ProjNet kullanma örneği verilmiştir.
public static class GeometryExtensions
{
private static readonly CoordinateSystemServices _coordinateSystemServices
= new CoordinateSystemServices(
new Dictionary<int, string>
{
// Coordinate systems:
[4326] = GeographicCoordinateSystem.WGS84.WKT,
// This coordinate system covers the area of our data.
// Different data requires a different coordinate system.
[2855] =
@"
PROJCS[""NAD83(HARN) / Washington North"",
GEOGCS[""NAD83(HARN)"",
DATUM[""NAD83_High_Accuracy_Regional_Network"",
SPHEROID[""GRS 1980"",6378137,298.257222101,
AUTHORITY[""EPSG"",""7019""]],
AUTHORITY[""EPSG"",""6152""]],
PRIMEM[""Greenwich"",0,
AUTHORITY[""EPSG"",""8901""]],
UNIT[""degree"",0.01745329251994328,
AUTHORITY[""EPSG"",""9122""]],
AUTHORITY[""EPSG"",""4152""]],
PROJECTION[""Lambert_Conformal_Conic_2SP""],
PARAMETER[""standard_parallel_1"",48.73333333333333],
PARAMETER[""standard_parallel_2"",47.5],
PARAMETER[""latitude_of_origin"",47],
PARAMETER[""central_meridian"",-120.8333333333333],
PARAMETER[""false_easting"",500000],
PARAMETER[""false_northing"",0],
UNIT[""metre"",1,
AUTHORITY[""EPSG"",""9001""]],
AUTHORITY[""EPSG"",""2855""]]
"
});
public static Geometry ProjectTo(this Geometry geometry, int srid)
{
var transformation = _coordinateSystemServices.CreateTransformation(geometry.SRID, srid);
var result = geometry.Copy();
result.Apply(new MathTransformFilter(transformation.MathTransform));
return result;
}
private class MathTransformFilter : ICoordinateSequenceFilter
{
private readonly MathTransform _transform;
public MathTransformFilter(MathTransform transform)
=> _transform = transform;
public bool Done => false;
public bool GeometryChanged => true;
public void Filter(CoordinateSequence seq, int i)
{
var x = seq.GetX(i);
var y = seq.GetY(i);
var z = seq.GetZ(i);
_transform.Transform(ref x, ref y, ref z);
seq.SetX(i, x);
seq.SetY(i, y);
seq.SetZ(i, z);
}
}
}
var seattle = new Point(-122.333056, 47.609722) { SRID = 4326 };
var redmond = new Point(-122.123889, 47.669444) { SRID = 4326 };
// In order to get the distance in meters, we need to project to an appropriate
// coordinate system. In this case, we're using SRID 2855 since it covers the
// geographic area of our data
var distanceInDegrees = seattle.Distance(redmond);
var distanceInMeters = seattle.ProjectTo(2855).Distance(redmond.ProjectTo(2855));
Dekont
4326, GPS ve diğer coğrafi sistemlerde kullanılan bir standart olan WGS 84'e karşılık gelir.
Ek kaynaklar
Veritabanına özgü bilgiler
Uzamsal verilerle çalışma hakkında ek bilgi için sağlayıcınızın belgelerini okuduğunuzdan emin olun.
- SQL Server Sağlayıcısında Uzamsal Veriler
- SQLite Sağlayıcısında Uzamsal Veriler
- Npgsql Sağlayıcısında Uzamsal Veriler