What would be the best way to structure a database and mvc app for the fastest look ups possible when trying to retrieve a list of items within a certain radius (in miles) and also depending on the item's zip code. I am open to suggestions even if it involves change to my current set up.
I am currently using a .txt file that contains zip codes and lat/lon coordinates to calculate distances. With the use of the Haversine Formula you can calculate distance between two points using the coordinates.
I am using PagedList 1.17.0.0
to page my data on my index controller. The main problem I am facing pertains to EF. When selecting items within a 50 mile distance my SQL statements become too nested and throw errors in EF.
Current Flow of controller
public ActionResult Index(string sortOrder, string Categories, string Manufacturers, int? page, bool clearFilters = false
,string DistanceLimit = "", int Vehicle = 0)
Each string in the parameters section is a possible filter for EF to use. Since I cannot tell EF to object.Where(P => P.Distance <= 50)
I generate a raw query using a string builder. My ZipCode class retrieves all zips within a 50 mile radius and then constructs a simple select with each zip code as a parameter in the where clause. This is where the problem occurs due to the fact that there are too many where clauses. 25 mile radius is fine, but not 50.
In the event that the above functionality works it fetches primary keys of items within that distance. I then have EF select Item.Include(P => P.Manufacturer).Include(P => P.Category).Include(3 other tables)
I then call ToList()
on my IQueryable
and remove any Item
s that are not within my previous list of PKs.
Finally, I call ToPagedList()
and return that to my view within a viewmodel.
As you can see there is alot going on here.
For One: it does not work past a 25 miles radius.
2: it is overly complex and feels like a Rube Goldberg machine.
3: All these separate query executions significantly impact search result speed.
As I said earlier, I am open to any suggestions from anyone who has made a system with similar functionality. I have never dealt with geospatial data and am recently aware of SQL Server's geography type; however, from my understanding, it seems that I would have to call StDistance
on every lat/lon record in order to figure out which items are near. Not to mention I will have to move my .txt file to the dB.