I'm trying to return a list of items that are within say 50 Miles of a given location.
My table (simplified) is as follows:
I've got an initial query:
var query = db.MyTable.Where(o=> o.Status == "New" && o.Active == true);
query = query.Where(o => new Point(o.Longitude, o.Latitude)
.IsWithinDistance(new Point(_currentLongitude, _currentLatitude), 50));
var result = query.ToList()
However - it doesn't seem to work and am getting an error as below - any ideas how to solve this? or if there is a better way to get the nearest items?
.Where(p => new Point(p.Longitude, p.Latitude) .IsWithinDistance(geom: __p_3,
distance: ___maxDistance_4))' could not be translated.Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Startup.cs:
services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
x => x.UseNetTopologySuite());
});
To make this feature work, you will need to have those coordinates stored as a Point in a SQL geography field. You can easily add this to your existing model as a computed column on a new property.
// on your entity
public Point Coordinates { get; }
// in your db context's OnModelCreating
modelBuilder.Entity<YourEntity>()
.Property(x => x.Coordinates)
.IsRequired()
.HasComputedColumnSql("geography::Point(Latitude, Longitude, 4326)");
Note, SRID 4326 is the commonly used lat/lon coordinate system supported by SQL Server. More on that here.
Build your model and deploy to your database.
Now that you have a spatial field and property, you can query like this:
var point = new Point(_currentLongitude, _currentLatitude) { SRID = 4326 };
var distanceInMeters = 50 * 1609.344; // 50 miles to meters conversion
var results = db.YourEntity
.Where(x => x.Coordinates.IsWithinDistance(point, distanceInMeters))
.ToList();
SRID 4326 uses meters for distance, so be sure to convert as shown above if you are using miles.
Also, if you have a lot of data you will also want to add a spatial index on that column, but EF Core doesn't support that directly yet so you'll have to do that directly in SQL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With