How to call user defined function in LINQ in my visual C# web service for my android application?

牧云@^-^@ 提交于 2019-12-19 09:24:33

问题


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

I have a database that store all the user location information in latitude and longitude. Since the calculation of distance between these two pairs of latitude and longitude is quite complicated, 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 the method and this method cannot be translated into a store expression.

I don't know how to translated it into a store expression and also, the calculation also need the math library.

Is there any method that i can do to let the LINQ expression call my own function?

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


回答1:


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

You should be able to construct a simple query that will serve your purposes with those 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 could construct a 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 would give you a box of points rather than a radius of points, but it would be few enough points that you could then process them and throw out the ones outside your radius. Or you might decide that a box is good enough for your purposes.




回答2:


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

this is not a Linq thing its a LinqToEntities restriction

you could put your code in to the database as a Stored Proc or Function and call it using ExecuteStoreQuery

see here Does Entity Framework Code First support stored procedures?




回答3:


The problem you see is that the LINQ to SQL engine is trying to inject T-SQL from your user-defined function and it cannot. One (albeit nasty) option is to retrieve all of your locations and then calculate 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();


来源:https://stackoverflow.com/questions/9789124/how-to-call-user-defined-function-in-linq-in-my-visual-c-sharp-web-service-for-m

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!