在LINQ查询中调用SQL用户定义的函数

我很难让这个工作。 我正在尝试使用IQueryable上的以下Filter助手进行半径搜索。 在RadiusSearch应用之前,还有一组其他filter可以应用。 顺序不应该真正重要,因为目标是将查询推迟到ToList()操作。

public static IQueryable RadiusSearch(this IQueryable 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 

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

这是您首先使用数据库或模型:

本文将介绍如何执行此操作: http : //msdn.microsoft.com/en-us/library/dd456847(VS.100).aspx

总而言之,首先需要在xml编辑器中编辑edmx文件,在edmx:StorageModels >> Schema部分中,您需要指定到sql udf的映射,例如

    

然后你需要在其上创建一个带有EdmFunction属性的静态函数,如下所示:

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

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

然后你可以这样称呼它:

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

希望这可以帮助。

如果您使用Code-First方法,那么您不能按照自己的意愿调用UDF(从EF6开始) – 这是certificate , 另一个是certificate 。 您只能将UDF作为SQL查询的一部分来调用:

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

这是丑陋的IMO,容易出错。

此外 – 这个MSDN页面说:

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

  1. 概念模型中定义函数或在存储模型中声明函数

这实际上意味着您需要使用Model-First方法来调用UDF。