Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les données spatiales représentent l’emplacement physique et la forme des objets. De nombreuses bases de données prennent en charge ce type de données afin qu’elles puissent être indexées et interrogées en même temps que d’autres données. Les scénarios courants incluent l’interrogation d’objets à une distance donnée à partir d’un emplacement ou la sélection de l’objet dont la bordure contient un emplacement donné. EF Core prend en charge le mappage aux types de données spatiales à l’aide de la bibliothèque spatiale NetTopologySuite.
Installation en cours
Pour utiliser des données spatiales avec EF Core, vous devez installer le package NuGet approprié. Le package que vous devez installer dépend du fournisseur que vous utilisez.
| Fournisseur EF Core | Spatial NuGet Package |
|---|---|
| Microsoft.EntityFrameworkCore.SqlServer | Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite |
| Microsoft.EntityFrameworkCore.Sqlite | Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite |
| Microsoft.EntityFrameworkCore.InMemory | NetTopologySuite |
| Oracle.EntityFrameworkCore | Oracle.EntityFrameworkCore.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 |
| FileBaseContext | NetTopologySuite |
NetTopologySuite
NetTopologySuite (NTS) est une bibliothèque spatiale pour .NET. EF Core facilite le mappage des types de données spatiales dans la base de données en utilisant des types NTS dans votre modèle.
Pour activer le mappage aux types spatiaux via NTS, appelez la méthode UseNetTopologySuite sur le générateur d’options DbContext du fournisseur. Par exemple, avec SQL Server, vous l’appelez comme suit.
options.UseSqlServer(
@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters;ConnectRetryCount=0",
x => x.UseNetTopologySuite());
Il existe plusieurs types de données spatiales. Le type que vous utilisez dépend des types de formes que vous souhaitez autoriser. Voici la hiérarchie des types NTS que vous pouvez utiliser pour les propriétés de votre modèle. Ils se trouvent dans l'espace de noms NetTopologySuite.Geometries.
- Géométrie
- Point
- LineString (Chaîne de lignes)
- Polygone
- GeometryCollection
- MultiPoint
- MultiLineString
- MultiPolygon
Avertissement
CircularString, CompoundCurve et CurePolygon ne sont pas pris en charge par NTS.
L’utilisation du type Geometry de base permet à n’importe quel type de forme d’être spécifié par la propriété.
Longitude et latitude
Les coordonnées dans NTS sont en termes de valeurs X et Y. Pour représenter la longitude et la latitude, utilisez X pour la longitude et Y pour la latitude. Notez qu’il s’agit d’un retour vers l’arrière du latitude, longitude format dans lequel vous voyez généralement ces valeurs.
Interrogation des données
Les classes d’entité suivantes peuvent être utilisées pour mapper des tables dans l’exemple de base de données Wide World Importers.
[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; }
}
Dans LINQ, les méthodes et propriétés NTS disponibles en tant que fonctions de base de données seront traduites en SQL. Par exemple, les méthodes Distance et Contains sont traduites dans les requêtes suivantes. Consultez la documentation de votre fournisseur pour laquelle les méthodes sont prises en charge.
// Find the nearest city
var nearestCity = await db.Cities
.OrderBy(c => c.Location.Distance(currentLocation))
.FirstOrDefaultAsync();
// Find the containing country
var currentCountry = await db.Countries
.FirstOrDefaultAsync(c => c.Border.Contains(currentLocation));
Ingénierie à rebours
Les packages NuGet spatiaux permettent également des modèles d’ingénierie inverse avec des propriétés spatiales, mais vous devez installer le package avant d’exécuter Scaffold-DbContext ou dotnet ef dbcontext scaffold. Si vous ne le faites pas, vous recevrez des avertissements concernant l'absence de mappages de type pour les colonnes, et celles-ci seront ignorées.
SRID ignoré pendant les opérations du client
NTS ignore les valeurs SRID pendant les opérations. Il suppose un système de coordonnées planaire. Cela signifie que si vous spécifiez des coordonnées en termes de longitude et de latitude, certaines valeurs évaluées par le client telles que la distance, la longueur et la zone seront en degrés, et non en mètres. Pour obtenir des valeurs plus significatives, vous devez d’abord projeter les coordonnées vers un autre système de coordonnées à l’aide d’une bibliothèque telle que ProjNet (pour GeoAPI).
Remarque
Utilisez le package NuGet ProjNet plus récent, et non le package plus ancien appelé ProjNet4GeoAPI.
Si une opération est évaluée par le serveur par EF Core via SQL, l’unité du résultat est déterminée par la base de données.
Voici un exemple d’utilisation de ProjNet pour calculer la distance entre deux villes.
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));
Remarque
4326 fait référence à WGS 84, norme utilisée dans le GPS et d’autres systèmes géographiques.
Ressources supplémentaires
Informations spécifiques à la base de données
Veillez à lire la documentation de votre fournisseur pour plus d’informations sur l’utilisation des données spatiales.
- Données spatiales dans le fournisseur SQL Server
- Données spatiales dans le fournisseur SQLite
- Données spatiales dans le fournisseur de données Oracle pour .NET
- Données spatiales dans le fournisseur Npgsql
Autres ressources
- NetTopologySuite Docs
- Session de standup de la communauté des données .NET, axée sur les données spatiales et NetTopologySuite.