Räumliche DatenSpatial Data

Hinweis

Diese Funktion wurde in EF Core 2,2 eingeführt.This feature was introduced in EF Core 2.2.

Räumliche Daten repräsentieren den physischen Speicherort und die Form von Objekten.Spatial data represents the physical location and the shape of objects. Viele Datenbanken unterstützen diese Art von Daten, damit Sie zusammen mit anderen Daten indiziert und abgefragt werden können.Many databases provide support for this type of data so it can be indexed and queried alongside other data. Häufige Szenarien umfassen das Abfragen von Objekten in einer bestimmten Entfernung von einem Speicherort oder das Auswählen des Objekts, dessen Rahmen eine bestimmte Position enthält.Common scenarios include querying for objects within a given distance from a location, or selecting the object whose border contains a given location. EF Core unterstützt die Zuordnung räumlicher Datentypen mithilfe der räumlichen Bibliothek nettopologysuite.EF Core supports mapping to spatial data types using the NetTopologySuite spatial library.

InstallationInstalling

Um räumliche Daten mit EF Core verwenden zu können, müssen Sie das entsprechende unterstützende nuget-Paket installieren.In order to use spatial data with EF Core, you need to install the appropriate supporting NuGet package. Welches Paket installiert werden muss, hängt vom verwendeten Anbieter ab.Which package you need to install depends on the provider you're using.

EF Core AnbieterEF Core Provider Räumliches nuget-PaketSpatial NuGet Package
Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.SqlServer Microsoft. entityframeworkcore. SqlServer. nettopologysuiteMicrosoft.EntityFrameworkCore.SqlServer.NetTopologySuite
Microsoft.EntityFrameworkCore.SqliteMicrosoft.EntityFrameworkCore.Sqlite Microsoft. entityframeworkcore. sqlite. nettopologysuiteMicrosoft.EntityFrameworkCore.Sqlite.NetTopologySuite
Microsoft.EntityFrameworkCore.InMemoryMicrosoft.EntityFrameworkCore.InMemory NettopologysuiteNetTopologySuite
Npgsql.EntityFrameworkCore.PostgreSQLNpgsql.EntityFrameworkCore.PostgreSQL Npgsql. entityframeworkcore. PostgreSQL. nettopologysuiteNpgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite
Pomelo.EntityFrameworkCore.MySqlPomelo.EntityFrameworkCore.MySql Pomelo. entityframeworkcore. MySQL. nettopologysuitePomelo.EntityFrameworkCore.MySql.NetTopologySuite
Devart.Data.MySql.EFCoreDevart.Data.MySql.EFCore Devart. Data. MySQL. efcore. nettopologysuiteDevart.Data.MySql.EFCore.NetTopologySuite
Devart.Data.PostgreSql.EFCoreDevart.Data.PostgreSql.EFCore Devart. Data. PostgreSQL. efcore. nettopologysuiteDevart.Data.PostgreSql.EFCore.NetTopologySuite
Devart.Data.SQLite.EFCoreDevart.Data.SQLite.EFCore Devart. Data. sqlite. efcore. nettopologysuiteDevart.Data.SQLite.EFCore.NetTopologySuite
Teradata.EntityFrameworkCoreTeradata.EntityFrameworkCore Teradata. entityframeworkcore. nettopologysuiteTeradata.EntityFrameworkCore.NetTopologySuite

NettopologysuiteNetTopologySuite

Nettopologysuite (NTS) ist eine räumliche Bibliothek für .net.NetTopologySuite (NTS) is a spatial library for .NET. EF Core ermöglicht die Zuordnung von räumlichen Datentypen in der Datenbank mithilfe von NTS-Typen in Ihrem Modell.EF Core enables mapping to spatial data types in the database by using NTS types in your model.

Um die Zuordnung räumlicher Typen über NTS zu ermöglichen, müssen Sie die usenettopologysuite-Methode für den dbcontext Options-Generator des Anbieters abrufen.To enable mapping to spatial types via NTS, call the UseNetTopologySuite method on the provider's DbContext options builder. Beispielsweise können Sie mit SQL Server wie folgt bezeichnen.For example, with SQL Server you'd call it like this.

options.UseSqlServer(
    @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters",
    x => x.UseNetTopologySuite());

Es gibt mehrere räumliche Datentypen.There are several spatial data types. Welcher Typ Sie verwenden, hängt von den Formen der Formen ab, die Sie zulassen möchten.Which type you use depends on the types of shapes you want to allow. Hier ist die Hierarchie der NTS-Typen, die Sie für Eigenschaften im Modell verwenden können.Here is the hierarchy of NTS types that you can use for properties in your model. Sie befinden sich im- NetTopologySuite.Geometries Namespace.They're located within the NetTopologySuite.Geometries namespace.

  • GeometrieGeometry
    • PointPoint
    • LineStringLineString
    • PolygonPolygon
    • GeometryCollectionGeometryCollection
      • MultiPointMultiPoint
      • MultiLineStringMultiLineString
      • MultiPolygonMultiPolygon

Warnung

Circularstring, compoundcurve und curepolygon werden von NTS nicht unterstützt.CircularString, CompoundCurve, and CurePolygon aren't supported by NTS.

Mit dem basisgeometry-Typ kann jeder Typ von Form von der-Eigenschaft angegeben werden.Using the base Geometry type allows any type of shape to be specified by the property.

Längen-und BreitengradLongitude and Latitude

Die Koordinaten in den NTS sind X-und Y-Werte.Coordinates in NTS are in terms of X and Y values. Um Längen-und Breitengrad darzustellen, verwenden Sie X für Längengrad und Y für Breitengrad.To represent longitude and latitude, use X for longitude and Y for latitude. Beachten Sie, dass dies nicht das latitude, longitude Format hat, in dem normalerweise diese Werte angezeigt werden.Note that this is backwards from the latitude, longitude format in which you typically see these values.

Abfrage von DatenQuerying Data

Die folgenden Entitäts Klassen können verwendet werden, um Tabellen in der Beispieldatenbank Wide World Importernzuzuordnen.The following entity classes could be used to map to tables in the Wide World Importers sample database.

[Table("Cities", Schema = "Application")]
internal class City
{
    public int CityID { get; set; }

    public string CityName { get; set; }

    public Point Location { get; set; }
}
[Table("Countries", Schema = "Application")]
internal class Country
{
    public int CountryID { get; set; }

    public string CountryName { get; set; }

    // Database includes both Polygon and MultiPolygon values
    public Geometry Border { get; set; }
}

In LINQ werden die NTS-Methoden und-Eigenschaften, die als Datenbankfunktionen verfügbar sind, in SQL übersetzt.In LINQ, the NTS methods and properties available as database functions will be translated to SQL. Beispielsweise werden die Distance-Methode und die-Methode in den folgenden Abfragen übersetzt.For example, the Distance and Contains methods are translated in the following queries. Informationen zu den unterstützten Methoden finden Sie in der Dokumentation des Anbieters.See your provider's documentation for which methods are supported.

// 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));

Reverse EngineeringReverse engineering

Die räumlichen nuget-Pakete ermöglichen auch die Reverse Engineering von Modellen mit räumlichen Eigenschaften. Sie müssen das Paket jedoch vor dem Ausführen von Scaffold-DbContext oder installieren dotnet ef dbcontext scaffold .The spatial NuGet packages also enable reverse engineering models with spatial properties, but you need to install the package before running Scaffold-DbContext or dotnet ef dbcontext scaffold. Wenn Sie dies nicht tun, erhalten Sie Warnungen, wenn Sie keine Typzuordnungen für die Spalten finden und die Spalten übersprungen werden.If you don't, you'll receive warnings about not finding type mappings for the columns and the columns will be skipped.

SRID wird bei Client Vorgängen ignoriert.SRID Ignored during client operations

NTS ignoriert SRID-Werte während des Vorgangs.NTS ignores SRID values during operations. Es wird von einem planaren Koordinatensystem ausgegangen.It assumes a planar coordinate system. Dies bedeutet Folgendes: Wenn Sie Koordinaten in Bezug auf Längengrad und Breitengrad angeben, werden einige vom Client ausgewertete Werte wie "Distance", "length" und "Area" in Grad und nicht in "Meter" angegeben.This means that if you specify coordinates in terms of longitude and latitude, some client-evaluated values like distance, length, and area will be in degrees, not meters. Wenn Sie aussagekräftigere Werte benötigen, müssen Sie die Koordinaten zunächst mithilfe einer Bibliothek wie projnet (für GeoAPI)einem anderen Koordinatensystem projizieren.For more meaningful values, you first need to project the coordinates to another coordinate system using a library like ProjNet (for GeoAPI).

Hinweis

Verwenden Sie das neuere projnet-nuget-Paket, nicht das ältere Paket mit dem Namen ProjNet4GeoAPI.Use the newer ProjNet NuGet package, not the older package called ProjNet4GeoAPI.

Wenn ein Vorgang vom Server durch EF Core über SQL ausgewertet wird, wird die Einheit des Ergebnisses von der Datenbank bestimmt.If an operation is server-evaluated by EF Core via SQL, the result's unit will be determined by the database.

Im folgenden finden Sie ein Beispiel für die Verwendung von projnet, um den Abstand zwischen zwei Städten zu berechnen.Here is an example of using ProjNet to calculate the distance between two cities.

internal 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));

Hinweis

4326 bezieht sich auf WGS 84, einen in GPS und anderen geografischen Systemen verwendeten Standard.4326 refers to WGS 84, a standard used in GPS and other geographic systems.

Zusätzliche RessourcenAdditional resources

Datenbankspezifische InformationenDatabase-specific information

Lesen Sie unbedingt die Dokumentation Ihres Anbieters, um weitere Informationen zum Arbeiten mit räumlichen Daten zu erhalten.Be sure to read your provider's documentation for additional information on working with spatial data.

Weitere RessourcenOther resources