2013-11-21 52 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

相關問題