2013-11-21 57 views
11

我很难让这个工作。我正在尝试在IQueryable上使用以下Filter助手进行半径搜索。还有一组其他过滤器在RadiusSearch应用之前应用。顺序应该不重要,因为目标是让查询延迟到ToList()操作。在LINQ查询中调用SQL用户定义的函数

public static IQueryable<ApiSearchCommunity> RadiusSearch(this IQueryable<ApiSearchCommunity> communities) 
{ 
    var centerLatitude = 30.421278; 
    var centerLongitude = -97.426261; 
    var radius = 25; 

    return communities.Select(c => new ApiSearchCommunity() 
    { 
     CommunityId = c.CommunityId, 
     City = c.City, 
     //Distance = c.GetArcDistance(centerLatitude, centerLongitude, c.Latitude, c.Longitude, radius) 
    }); 
} 

可不知何故,我写这样GetArcDistance一个帮手以上,后者又调用SQL上一个UDF?我试图生成查询如下

SELECT 
    comms.community_id, 
    comms.city, 
    comms.distance 
FROM (
    SELECT 
     c.community_id, 
     c.city, 
     dbo.udf_ArcDistance(
      30.421278,-97.426261, 
      c.community_latitude, 
      c.community_longitude 
     ) AS distance 
    FROM communities c) AS comms 
WHERE comms.distance <= 25 
ORDER BY comms.distance 
+0

您使用的是什么版本的实体框架? –

+0

我正在使用版本5。 – Praveen

+1

您是否检查过EF中的空间类型支持? http://msdn.microsoft.com/en-us/data/hh859721.aspx –

回答

19

好吧,我想我理解这个问题 - 它的要点是你想能够调用一个SQL UDF作为你的Linq to Entities查询的一部分。

这是如果你使用的数据库或模式第一:

本文介绍了如何做到这一点:http://msdn.microsoft.com/en-us/library/dd456847(VS.100).aspx

概括起来,首先需要编辑您的EDMX文件的XML编辑器在EDMX:StorageModels >>架构部分,你需要指定一个映射到SQL UDF,如

<Function Name="SampleFunction" ReturnType="int" Schema="dbo"> 
    <Parameter Name="Param" Mode="In" Type="int" /> 
</Function> 

然后,你需要的地方创建一个静态函数就可以了EdmFunction属性,是这样的:

public static class ModelDefinedFunctions 
{ 
    [EdmFunction("TestDBModel.Store", "SampleFunction")] 
    public static int SampleFunction(int param) 
    { 
     throw new NotSupportedException("Direct calls are not supported."); 
    } 
} 

此方法将在实体框架的查询时间映射到UDF。第一个属性参数是商店命名空间 - 您可以在Schema元素的edmx xml文件中找到它(查找命名空间)。第二个参数是udf的名称。

然后,您可以调用它是这样的:

var result = from s in context.UDFTests 
      select new 
      { 
       TestVal = ModelDefinedFunctions.SampleFunction(22) 
      }; 

希望这有助于。

+0

你应该能够把它称为任何一部分IQueryable - 当实体框架然后评估您的表达式时,它将从属性映射中知道它应该在该场景中使用SQL UDF。你现在在哪里定义了GetArcDistance方法? –

14

如果使用Code-First的方法,那么你不能调用UDF的,只要你想(如EF6的) - 这里是proofanother one。你只限于调用UDF作为part of your SQL query

bool result = FooContext.CreateQuery<bool>(
    "SELECT VALUE FooModel.Store.UserDefinedFunction(@someParameter) FROM {1}", 
    new ObjectParameter("someParameter", someParameter) 
).First(); 

这是IMO难看,而且容易出错。

而且 - 这MSDN页说:

调用自定义函数的过程需要三个基本步骤:

  1. 定义一个函数在概念模型或在您的存储声明函数型号为

这基本上意味着你需要使用Model-First方法调用的UDF。

+0

我正在使用Model-First。 – Praveen

+1

好的 - 然后@马特的答案是你所需要的。如果有人会搜索,我会保留我的答案。 – avs099

+0

是的,我正在寻找代码的第一个版本,我会发布什么似乎是一个工作要求...创建一个内联的SQL调用,并返回所需的值 – Clarence

相关问题