我有一个标量函数,可以获取两点之间的距离,我想用它来查询最近的记录到点。标量函数适用于 linq to sql 但因 EF 失败
标量函数
USE [GeoData]
GO
/****** Object: UserDefinedFunction [dbo].[DistanceBetween] Script Date: 09/18/2012 19:40:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[DistanceBetween](@Lat1 as real,
@Long1 as real, @Lat2 as real, @Long2 as real)
RETURNS real
AS
BEGIN
DECLARE @dLat1InRad as float(53);
SET @dLat1InRad = @Lat1;
DECLARE @dLong1InRad as float(53);
SET @dLong1InRad = @Long1;
DECLARE @dLat2InRad as float(53);
SET @dLat2InRad = @Lat2;
DECLARE @dLong2InRad as float(53);
SET @dLong2InRad = @Long2 ;
DECLARE @dLongitude as float(53);
SET @dLongitude = @dLong2InRad - @dLong1InRad;
DECLARE @dLatitude as float(53);
SET @dLatitude = @dLat2InRad - @dLat1InRad;
/* Intermediate result a. */
DECLARE @a as float(53);
SET @a = SQUARE (SIN (@dLatitude / 2.0)) + COS (@dLat1InRad)
* COS (@dLat2InRad)
* SQUARE(SIN (@dLongitude / 2.0));
/* Intermediate result c (great circle distance in Radians). */
DECLARE @c as real;
SET @c = 2.0 * ATN2 (SQRT (@a), SQRT (1.0 - @a));
DECLARE @kEarthRadius as real;
/* SET kEarthRadius = 3956.0 miles */
SET @kEarthRadius = 6376.5; /* kms */
DECLARE @dDistance as real;
SET @dDistance = @kEarthRadius * @c;
return (@dDistance);
END
GO
我添加了一个 ado.net 实体模型,从数据库中更新了模型并选择了距离
<Function Name="DistanceBetween" ReturnType="real" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<Parameter Name="Lat1" Type="real" Mode="In" />
<Parameter Name="Long1" Type="real" Mode="In" />
<Parameter Name="Lat2" Type="real" Mode="In" />
<Parameter Name="Long2" Type="real" Mode="In" />
</Function>
我做了一个部分类并写了这个方法
public partial class GeoDataEntities
{
[EdmFunction("GeoDataModel.Store", "DistanceBetween")]
public double DistanceBetween(double lat1, double lon1, double lat2, double lon2)
{
throw new NotImplementedException();
}
}
我多次尝试使用此代码查询函数,但出现错误
var NParcel = db.geoAddresses.Where(g=> db.DistanceBetween(21.5,39.5, g.lat,g.lon) < 20);
当我尝试count
使用foreach
NParcel 时,我收到此错误
'EFSample.GeoDataEntities' 类型上的指定方法 'Double DistanceBetween(Double, Double, Double, Double)' 无法转换为 LINQ to Entities 存储表达式。
和堆栈跟踪
在 System.Data.Objects.ELinq.ExpressionConverter.ThrowUnresolvableFunction(Expression Expression) 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.FunctionCallTranslator.TranslateFunctionCall(ExpressionConverter parent, MethodCallExpression call, EdmFunctionAttribute functionAttribute) 在 System.Data.Objects.ELinq .ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) 在 System.Data.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq) 在 System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)在 System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda,DbExpression 输入)在 System.Data.Objects.ELinq。System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) 在 System.Data. .Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) 在 System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.AggregateTranslator.Translate( ExpressionConverter 父级,MethodCallExpression 调用)在 System.Data.Objects.ELinq.ExpressionConverter。System.Data.Objects.ELinq.ExpressionConverter.Convert() 在 System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable) 的 MethodCallTranslator.TypedTranslate(ExpressionConverter parent,MethodCallExpression linq)
1 forMergeOption) at System.Data.Objects.ObjectQuery
1.GetResults(在 System.Linq.Enumerable.Single[TSource] 处为 Nullable1 forMergeOption) at System.Data.Objects.ObjectQuery
1.System.Collections.Generic.IEnumerable.GetEnumerator()(IEnumerable1 source) at System.Linq.Queryable.Count[TSource](IQueryable
1 源)