Как вызвать пользовательскую функцию в LINQ в моем визуальном веб-сервисе C # для моего приложения для Android? - PullRequest
3 голосов
/ 20 марта 2012

В настоящее время я работаю над приложением, которое будет извлекать местоположения других пользователей на основе расстояния.

У меня есть база данных, в которой хранится вся информация о местоположении пользователя по широте и долготе. Поскольку вычисление расстояния между этими двумя парами широты и долготы довольно сложно, мне нужна функция для его обработки.

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

Однако я получил следующую ошибку: LINQ to Entities не распознает метод, и этот метод нельзя преобразовать в выражение хранилища.

Я не знаю, как перевести его в выражение магазина, а также, для расчета также нужна математическая библиотека.

Есть ли какой-нибудь метод, который я могу сделать, чтобы выражение LINQ вызывало мою собственную функцию?

Может быть, есть другие способы достичь моей цели, кто-нибудь может помочь?

Ответы [ 3 ]

1 голос
/ 20 марта 2012

LinqToEntities не позволяет вам вызывать функцию, она даже не позволяет ToString ()

это не вещь Linq, а ограничение LinqToEntities

Вы можете поместить свой код в базу данных в качестве сохраненного процесса или функции и вызвать его с помощью ExecuteStoreQuery

см. Здесь Поддерживает ли Entity Framework Code First хранимые процедуры?

0 голосов
/ 20 марта 2012

Я действительно не знаю LINQ, но, предполагая, что вы можете отправлять только простые ограничения в запросе, я бы сконструировал метод, который в основном делает обратное calDistance - взять координату и расстояние и преобразовать их в ограничивающую рамку с минимальной долготой, максимальной долготой, минимальной широтой и максимальной широтой.

Вы должны быть в состоянии создать простой запрос, который будет соответствовать вашим целям с этими ограничениями.

что-то вроде (используя Java здесь):

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;
}

Тогда вы могли бы построить запрос.

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]

Это даст вам коробку точек, а не радиус точек, но будет достаточно нескольких точек, чтобы вы могли обработать их и выбросить те, которые находятся за пределами вашего радиуса. Или вы можете решить, что ящик достаточно хорош для ваших целей.

0 голосов
/ 20 марта 2012

Проблема, которую вы видите, состоит в том, что движок LINQ to SQL пытается внедрить T-SQL из вашей пользовательской функции, но не может. Один (хотя и неприятный) вариант - получить все ваши местоположения, а затем рассчитать на основе этого набора результатов.

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