How do I call a user defined function in LINQ in my C # visual web service for my android app?

I am currently working on an application that will fetch other users' locations based on distance.

I have a database that stores all the user's location information in latitude and longitude. Since calculating the distance between these two latitude and longitude pairs is quite difficult, I need a function to handle it.

from a in db.Location.Where(a => (calDistance(lat, longi, Double.Parse(a.latitude), Double.Parse(a.longitude)))<Math.Abs(distance)  )) {...}


However, I got the following error: LINQ to Entities does not recognize a method and this method cannot be translated into a store expression.

I don't know how to translate it into a store expression, and it also needs a math library to calculate.

Is there any method I can do to make the LINQ expression call my own function?

Perhaps there are other ways to achieve my goal, can anyone help?


source to share

3 answers

I don't know LINQ, but assuming you can only send simple constraints in the query, I would build a method that basically does the inverse of calDistance - take coordinate and distance and convert it to a bounding box with min longitude, max longitude, min latitude and maximum latitude.

You should be able to create a simple query that serves your purpose with these constraints.

something like (using Java here):

public double[] getCoordinateBounds(double distance, double longitude, double latitude) {
    double[] bounds = new double[4];
    bounds[0] = longitude - distanceToLongitudePoints * (distance);
    bounds[1] = longitude + distanceToLongitudePoints * (distance);
    bounds[2] = latitude - distanceToLatitudePoints * (distance);
    bounds[3] = latitude + distanceToLatitudePoints * (distance);
    return bounds;


Then you can build your query.

double[] bounds = getCoordinateBounds(distance, longi, lat);
var nearbyUserLocations = from a in db.Location 
                         where longitude > bounds[0] and longitude < bounds[1]
                            and latitude > bounds[2] and latitude < bounds[3]


This will give you a field of points, not a radius of points, but there will be enough points that you can process and throw out of your radius. Or, you may decide that the box is good enough for your purposes.



LinqToEntities won't let you call a function, it doesn't even allow ToString ()

this is not a Linq thing, its a LinqToEntities limitation

you can put your code in a database as a stored procedure or function and call it using ExecuteStoreQuery

see here Is Entity Framework Code the first to support stored procedures?



The problem you are seeing is that the LINQ to SQL engine is trying to inject T-SQL from your UDF, and this is not possible. One (albeit nasty) option is to extract all of your locations and then compute from that result set.

var locations = db.Location.ToList();
locations = locations.Where(a => (calDistance(lat, longi, Double.Parse(a.latitude), Double.Parse(a.longitude))).ToList();




All Articles