Räumliche Daten
Räumliche Daten stellen die physische Position und die Form von Objekten dar. Viele Datenbanken unterstützen diese Art von Daten, sodass sie zusammen mit anderen Daten indiziert und abgefragt werden können. Häufige Szenarien sind das Abfragen von Objekten innerhalb einer bestimmten Distanz von einer Position oder die Auswahl des Objekts, dessen Rand eine bestimmte Position enthält. EF Core unterstützt die Zuordnung zu räumlichen Datentypen mithilfe der räumlichen NetTopologySuite-Bibliothek.
Installieren von
Um räumliche Daten mit EF Core zu verwenden, müssen Sie das entsprechende unterstützende NuGet-Paket installieren. Welches Paket Sie installieren müssen, hängt vom Anbieter ab, den Sie verwenden.
EF Core-Anbieter | Spatial NuGet-Paket |
---|---|
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) ist eine räumliche Bibliothek für .NET. EF Core ermöglicht die Zuordnung zu räumlichen Datentypen in der Datenbank mithilfe von NTS-Typen in Ihrem Modell.
Um die Zuordnung zu räumlichen Typen über NTS zu ermöglichen, rufen Sie die UseNetTopologySuite-Methode im DbContext-Optionengenerator des Anbieters auf. Bei SQL Server sähe der Aufruf z. B. wie folgt aus.
options.UseSqlServer(
@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters;ConnectRetryCount=0",
x => x.UseNetTopologySuite());
Es gibt mehrere räumliche Datentypen. Welchen Typ Sie verwenden, hängt von den Typen von Formen ab, die Sie zulassen möchten. Dies ist die Hierarchie von NTS-Typen, die Sie für Eigenschaften in Ihrem Modell verwenden können. Sie befinden sich im NetTopologySuite.Geometries
-Namespace.
- Geometrie
- Point
- LineString
- Polygon
- GeometryCollection
- MultiPoint
- MultiLineString
- MultiPolygon
Warnung
CircularString, CompoundCurve und CurePolygon werden von NTS nicht unterstützt.
Mithilfe des Basisgeometrietyps kann jeder Typ von Formen durch die Eigenschaft angegeben werden.
Breitengrad und Längengrad
Koordinaten in NTS beziehen sich auf X- und Y-Werte. Um Längengrad und Breitengrad darzustellen, verwenden Sie X für den Längengrad und Y für den Breitengrad. Beachten Sie, dass dies umgekehrt ist wie beim latitude, longitude
-Format, in dem Sie diese Werte normalerweise sehen.
Abfrage von Daten
Die folgenden Entitätsklassen können zur Zuordnung zu Tabellen in der Wide World Importers-Beispieldatenbank verwendet werden.
[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; }
}
In LINQ werden die NTS-Methoden und -Eigenschaften, die als Datenbankfunktionen verfügbar sind, in SQL übersetzt. Die Methoden „Distance“ und „Contains“ werden beispielsweise in die folgenden Abfragen übersetzt. Entnehmen Sie der Dokumentation Ihres Anbieters, welche Methoden unterstützt werden.
// 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 Engineering
Die räumlichen NuGet-Pakete ermöglichen auch Reverse Engineering-Modelle mit räumlichen Eigenschaften, aber Sie müssen das Paket installieren, bevor Scaffold-DbContext
oder dotnet ef dbcontext scaffold
ausgeführt wird. Andernfalls erhalten Sie Warnungen darüber, dass keine Typzuordnungen für die Spalten gefunden werden, und die Spalten werden übersprungen.
SRID wird während Clientvorgängen ignoriert
NTS ignoriert SRID-Werte während des Betriebs. Es wird ein planares Koordinatensystem vorausgesetzt. Dies bedeutet: Wenn Sie Koordinaten in Längengrad und Breitengrad angeben, werden einige vom Client ausgewertete Werte wie Entfernung, Länge und Fläche in Grad und nicht in Metern angegeben. Für aussagekräftigere Werte müssen Sie zunächst die Koordinaten mithilfe einer Bibliothek wie ProjNet (für GeoAPI) auf ein anderes Koordinatensystem projizieren.
Hinweis
Verwenden Sie das neuere ProjNet NuGet-Paket, nicht das ältere Paket mit dem Namen ProjNet4GeoAPI.
Wenn ein Vorgang serverseitig von EF Core über SQL ausgewertet wird, wird die Einheit des Ergebnisses von der Datenbank bestimmt.
Hier ist ein Beispiel für die Verwendung von ProjNet zum Berechnen der Entfernung zwischen zwei Städten.
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));
Hinweis
4326 bezieht sich auf WGS 84, einen Standard, der in GPS und anderen geografischen Systemen verwendet wird.
Zusätzliche Ressourcen
Datenbankspezifische Informationen
Lesen Sie unbedingt die Dokumentation Ihres Anbieters, um weitere Informationen zum Arbeiten mit räumlichen Daten zu erhalten.
- Räumliche Daten im SQL Server-Anbieter
- Räumliche Daten im SQLite-Anbieter
- Räumliche Daten im Npgsql-Anbieter
Weitere Ressourcen
- NetTopologySuite-Dokumentation
- .NET Data Community Standup-Sitzung mit Konzentration auf räumliche Daten und NetTopologySuite.