Aracılığıyla paylaş


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.

Diğer kaynaklar