Entity Framework Core 2.2 Preview 2 – données spatiales
Ca y est, Entity Framework Core supporte les données spatiales avec la sortie de la version 2.2 Preview 2. Regardons comment nous en servir.
Pre-requis
Code
Ajouter le package Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite qui est disponible en prerelease pour l’instant.
Dans la preview 2, les type spatiaux ne sont pas supportés par la commande Scaffold-DbContext.
PM> Scaffold-DbContext "Data Source=..." Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Force
Could not find type mapping for column 'dbo.Events.EventLocation' with data type 'geography'. Skipping column.Il faut alors les ajouter manuellement dans les modèles. A noter que l’approche code first quant à elle fonctionne.
using NetTopologySuite.Geometries;
//...
public partial class Events
{
public int Id { get; set; }
public string Title { get; set; }
public Point EventLocation { get; set; }
}
Une fois le package installé, il faut activer la gestion des données spatiales dans le DBContext en appelant UseNetTopologySuite() dans UseSqlServer() dans OnConfiguring() ou dans AddDbContext().
services.AddDbContext(
options =>
options.UseSqlServer("Data Source=...",
sqlOptions => sqlOptions.UseNetTopologySuite()));
Il est maintenant possible de manipuler ces types.
using (TestContext testContext = new TestContext())
{
// Insert
testContext.Events.AddRange(
new Events
{
Id = 100,
Title = "E14",
EventLocation = new NetTopologySuite.Geometries.Point(1, 4) { SRID = 4326 }
},
new Events
{
Id = 101,
Title = "E41",
EventLocation = new NetTopologySuite.Geometries.Point(4, 1) { SRID = 4326 }
}
);
testContext.SaveChanges();
// display
var v = testContext.Events;
Console.WriteLine($"Title - EventLocation.AsText()");
foreach (var e in v)
{
Console.WriteLine($"{e.Title} - {e.EventLocation.AsText()}");
}
}
et voici le résultat dans la console
Title - EventLocation.AsText()
E14 - POINT (1 4)
E41 - POINT (4 1)ASP.Net Core MVC
J’ai testé avec ASP.Net Core MVC et la génération de contrôleur et vues fonctionne.
Il est possible d’aller plus loin, comme en cherchant les points à proximité d’un autre point.
public async Task Near()
{
Point point = new Point(3, 0) { SRID = 4326 };
return View(await _context.Events
//.Where(e => e.EventLocation.Distance(point) < x)
.OrderBy(e => e.EventLocation.Distance(point))
.Take(3)
.ToListAsync());
}
et voici le résultat :
Cette preview va dans la bonne direction.
DotNet Core devrait toucher un public plus large avec cette fonctionnalité qui était attendue depuis longtemps par la communauté.
**Références : **