2015-11-06 25 views
5

我有一個工作(簡化)ODataController以下方法。如何實例化ODataQueryOptions

public class MyTypeController : ODataController 
{ 
    [HttpGet] 
    [EnableQuery] 
    [ODataRoute("myTypes")] 
    public IQueryable<MyType> GetMyTypes(ODataQueryOptions<MyType> options) 
    { 
    return _repo.myResultsAsQueryable(); 
    } 
} 

我想能夠從服務器調用此方法要做到這一點,我需要實例化一個ODataQueryOptions這需要一個ODataQueryContext

有一些如何做到這一點的例子(例如,herehere),但它們似乎都參考了先前版本的OData。構造函數ODataQueryContext當前需要第三個參數(ODataPath路徑),這在我找不到的任何示例中都未涉及。

編輯: @snow_FFFFFF,這裏的一些背景。我知道我可以簡單地通過HttpClient的消費OData的終點,但我想與IQueryable的直接照你說的互動。

問題是,我正在處理的應用程序允許用戶創建可以保存並由其他用戶隨後調用的過濾器(如複雜的搜索引擎)。從JS客戶端,他們只需通過id查找過濾器,然後使用應用於查詢字符串的過濾器對OData端點發出查詢。這在客戶端非常有效,但我希望能夠在服務器端做類似的事情。

這是我想要做的,但我如何實例化ODataPath參數?

public IQueryable<MyType> FilterMyTypes(int filterID) 
{ 
    // lookup filter by filterID from db... 
    filter = "$filter=Status eq 1"; // for example... 

    ODataPath path = // but how can I get the path!!! 
    new ODataQueryContext(edmModel, typeof(MyType), path); 

    var uri = new HttpRequestMessage(HttpMethod.Get, "http://localhost:56339/mytypes?" + filter); 
    var opts = new ODataQueryOptions<MyType>(ctx, uri); 

    var results = new MyTypeController().GetMyTypes(opts); 
} 

這樣做的另一個應用是如下支持動態分組:

[HttpGet] 
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")] 
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName) 
{ 
    // For example: get all Active MyTypes and group by AssignedToUserID... 

    // Get the results of the filter as IQueryable... 
    var results = FilterMyTypes(filterID); 

    // group on groupByFieldName 
    var grouped = results.GroupBy(x => GetPropertyValue(x,groupByFieldName)); 

    // select the groupByFieldName and the count 
    var transformedResults = grouped.Select(g => new { g.Key, Count = g.Count() }); 

    return Ok(transformedResults); 
} 
+1

在http://github.com/OData/WebApi中,有很多可以引用的測試用例。例如,ODataQueryContext,你可以參考:https://github.com/OData/WebApi/blob/master/OData/test/UnitTest/System.Web.OData.Test/OData/Query/ODataQueryContextTests.cs#L181- L200 –

+0

謝謝山姆,我會盡力..不習慣MS開源... –

+0

山姆。你真棒!如果你把答案放在答案中,我可以接受它。非常感謝。像魅力一樣工作。 –

回答

3

肯定。 ODataPath是應跟進OData Uri spec的ODataPathSegment的列表。

在網頁API的OData,很容易實例化一個ODataPath,例如:

IEdmModel model = GetEdmModel(); 
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet(setName); 
ODataPath path = new ODataPath(new EntitySetPathSegment(entitySet)); 

以上path跟進的OData的規範,它具有OData的模板:

~/entityset 

更多可以找到測試用例(代碼)here

+1

截止到2017年5月25日,Microsoft.AspNet.OData的最新穩定版本是v6.0.0。似乎不再有一個'EntitySetPathSegment'類。我需要在NuGet中降級到5.9.1。否則,非常有幫助的問題,我非常欣賞鏈接到源代碼測試用例。 – asporter

+0

截至今天爲止。 –

0

你的OData控制器提供HTTP接口,你的數據,你不應該通過HTTP訪問它(即使從服務器)?有一個VS插件生成這裏的OData客戶端代碼:

https://visualstudiogallery.msdn.microsoft.com/9b786c0e-79d1-4a50-89a5-125e57475937

或者,如果你是從同一個項目,爲什麼不返回的IQueryable的,可以從被稱爲通用的方法中這樣做你的代碼還是來自控制器?

UPDATE:基於在原來的問題的更多信息:

如果你有一個控制器的方法定義ODataQueryOptions,它可以讓你解析正在調用該方法,形成良好的OData查詢。當我需要翻譯odata查詢的某些部分時,我使用了這個功能,因爲我需要查詢多個數據源才能返回最終結果。

這聽起來像你想要的東西,需要非OData的參數和選項。對於這一點,你可能需要看看自定義操作和或功能(如果你只是返回的數據,可能是一個函數):

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions

更新#2:還有更詳細的閱讀之後,我覺得我錯過了你的觀點 - 我沒有答案,但我會玩弄它。難道你不能改變URL本身(而不是實例化查詢選項?

更新#3:我認爲你將有一個很難欺騙它,以爲它是得到一個OData的請求......這是不是一個真正的OData的請求。回到我原來的答覆中提到的第二個方案 - 爲什麼不,您可以使用和OData的控制器可以使用一個通用的方法 - 是這樣的:

// some sort of helper class 
public class HelperObject 
{ 
    public static IQueryable<MyType> GetGroupedValues(int filterID, string groupByFieldName) 
    { 
     // all your code/logic here 
    } 
} 

// your odata controller uses the helper 
[HttpGet] 
[Route("myTypes/{filterID:int}/groupby/{groupByFieldName}")] 
public IHttpActionResult GroupMyTypes(int filterID, string groupByFieldName) 
{ 
    return Ok(HelperObject.GetGroupedValues(filterID, groupByFieldName)); 
} 

// ... and so does your other code that wants to do the same thing 
var x = HelperObject.GetGroupedValues(filterID, groupByFieldName);