I had the following code
query = query.Where(device => GetDeviceDistanceFromGeocode(geocode, device) <= distanceMetres);
private static double GetDeviceDistanceFromGeocode(Geocode geocode, Device device)
{
return Math.Pow(
Math.Pow(device.Address.Geocode.Easting - geocode.Easting, 2) +
Math.Pow(device.Address.Geocode.Northing - geocode.Northing, 2)
, 0.5);
}
However it throws an exception because linq cannot recognise my function forcing me into doing the whole query expression in one go.
Exception[LINQ to Entities does not recognize the method
'Double DistanceOfDeviceFromGeocode(Geocode, Device)' method,
and this method cannot be translated into a store expression.]
Is it possible to break a query expression out into multiple parts like i’m trying to do here? It’s not very readable when the query is so big.
EDIT:
Here’s the full query as asked for in the comments.
return query.Where(device =>
Math.Pow(
Math.Pow(device.Address.Geocode.Easting - geocode.Easting, 2) +
Math.Pow(device.Address.Geocode.Northing - geocode.Northing, 2)
, 0.5)
<= distanceMetres);
Basically I don’t think this is very readable so would like to break it down into multiple parts but from the links supplied it doesn’t seem possible.
In c++ I could have broken some of it out into a macro but unfortunately this isn’t a feature of c#.
Following suggestions I’ve updated the code to this which works quite nicely and improves the readability of the code a lot!
return query.Where( DevicesWithinDistanceFromGeocode(distanceMetres, geocode) );
}
public Expression<Func<Device, bool>> DevicesWithinDistanceFromGeocode(double distance, Geocode geocode)
{
return device => ( SqlFunctions.SquareRoot(
SqlFunctions.Square((double)(device.Address.Geocode.Easting - geocode.Easting)) +
SqlFunctions.Square((double)(device.Address.Geocode.Northing - geocode.Northing))
) <= distance );
}
Technically there are ways to do it, however since Linq can’t directly translate your custom code to SQL they require returning ALL results to Linq and then evaluating the custom methods.
Since you’re using this in a
Whereclause I’m assuming that you expect to retrieve a relatively small number of records. In that case I would recommend coding your condition in SQL, either in a stored procedure or scalar-valued function, then using that sproc/function in your Linq-to-Entities query.