mvc api odata 查詢選項之 $inlinecount ,$format 選項

網上百度“odata 語法”會出來很多結果,其中有一項是比較一致的,那就是odata支持一下幾種語法:

$filter  條件表達式 -- 對應sql語句的where條件查詢,如:/Categories?$filter=name eq 'liumang'

$expand 包含屬性和關係 -- 對應表的外鍵關係,如:/Categories?$expand=Products

$select 查詢字段的列表 -- 對應sql語句select後面的字段,如:/Categories?$select=id,name

$count 查詢數量 -- 根據當前查詢條件返回的總記錄數,如Categories表中有10條記錄,則/Categories?count 或者 /Categories?count=true

(ps:這條我沒有找到具體確切的用法,在AllowedQueryOptions 枚舉中也沒有列出這條選項)

$orderby  排序 -- 對應sql語句order by語句,如:/Categories?$orderby=id,name ,/Categories?$orderby=id,name desc(asc) ,/Categories?$orderby=id desc,name asc

$skip 當前查詢跳過多少條數據,再返回查詢結果,如:/Categories?$orderby=id&$skip=10,如果id是連續的話,那麼返回從id=11之後的所有數據

$top  返回當前查詢的前多少條數據,如/Categories?$top=10

skip 和top 一般是配合一起使用,用來做分頁查詢,如/Categories?$skip=10&$top=10 ,/Categories?$skip=20&$top=10 ,這樣就可以做出一個pagesize 爲10的分頁查詢了

$inlinecount 返回當前查詢條件的所有記錄數,如:/Categories?$inlinecount=allpages ,如果Categories有23條數據,則返回23

$skiptoken 例如遊標或者書籤的一個東西

$metadata  顯示元數據

以上是在網上找到的相關資料,資料很齊全,很多都給出了案列,但是在我實際的使用中,卻只有幾項數據能夠使用,其他的都不適用,我分析原因可能如下 :

1:我做的項目是集成在mvc和api裏面的,而網上的很多例子大都是wcf的案列,我不太清楚是不是這個原因,因爲wcf我只知道皮毛,沒有深入

2:在程序集 System.Web.Http.OData.dll, v4.0.0.0 中有這樣一段註釋:

     //
        // 摘要:
        //     獲取或設置允許在查詢內部使用的查詢參數。默認值爲所有查詢選項,包括 $filter、$skip、$top、$orderby、$expand、$select、$inlineCount、$format
        //     和 $skipToken。
        //
        // 返回結果:
        //     返回 System.Web.Http.OData.Query.AllowedQueryOptions。
    public AllowedQueryOptions AllowedQueryOptions { get; set; }

可以看出 AllowedQueryOptions 枚舉和上面列出的還是有一些出入的

3:同樣在程序集 System.Web.Http.OData.dll, v4.0.0.0 中還有這樣一段註釋:

   namespace System.Web.Http.OData.Query

   // 摘要:
    //     此項定義可用於執行查詢撰寫的複合 OData 查詢選項。此項當前僅支持 $filter、$orderby、$top 和 $skip。
    //
    // 類型參數:
    //   TEntity:
    [ODataQueryParameterBinding]
    public class ODataQueryOptions<TEntity> : ODataQueryOptions

可以看出只支持四個選項,這和我在項目中的使用情況是一致的。

ps:讓我疑惑的一點就是,odata 4.0裏面是支持我上面列出的所有查詢選項的,而在api 2.2發佈的時候則是明確表示支持odata 4.0的,我不知道是什麼原因導致我現在的項目中只支持四個選項.

 

說了這麼多後,回到主題上面來,在項目中其實 $filter、$orderby、$top 和 $skip 四個選項是可以支持90%左右的查詢功能的

其餘10%的功能比如:分頁查詢時必須知道的總記錄數、返回json字符串、外鍵關係等

下面說一下我在網上查到的關於$inlinecount ,$format的解決方法

$format

需要odata支持$format參數只需要一句語句即可

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
       //添加下面這句代碼即可支持$format查詢選項,當然需要添加程序集 System.Net.Http.Formatting.dll config.Formatters.JsonFormatter.AddQueryStringMapping(
"$format", "json", "application/json"); } }

 

$inlinecount

這個也不需要太多複雜的操作,代碼如下

public class testController : ApiController
    {
        testBLL DB = new testBLL();
        public PageResult<dict> Get(ODataQueryOptions<dict> options)
        {
            int pageSize = 10; 
            ODataQuerySettings settings = new ODataQuerySettings()
            {
                PageSize = pageSize
            };

            IQueryable results = options.ApplyTo(DB.FindAll().AsQueryable(), settings);

            return new PageResult<dict>(
                results as IEnumerable<dict>,
                Request.GetNextPageLink(),
                Request.GetInlineCount());
        }
    }

查詢url : http://localhost:3812/api/test?$skip=20&$inlinecount=allpages

返回格式如下:

  "Items": ["json字符串"],
  "NextPageLink" :"下一頁url",
  "Count": number//總記錄數
}
參考網絡資料:http://www.2cto.com/kf/201312/266851.html
在這裏我做了一個實驗,因爲在實際的案列環境中,用戶是可以自己選擇每頁顯示記錄數的,但是這個列子裏面卻是寫死的。
所以我修改了一下代碼如下:
int pageSize = options.Top == null ? 10 : options.Top.Value;

在用戶選擇了記錄數時,按照用戶選擇的設置,可以動態的返回下一頁的記錄,但是返回的NextPageLink的值卻爲null,當我去掉top參數時,返回是正常數據

下面是反編譯了System.Web.Http.OData.dll之後的源代碼 ,我想可能在請求發送過來,在設置參數的時候,判斷了過top參數所導致的

public static Uri GetNextPageLink(this HttpRequestMessage request)
{
    object obj2;
    if (request == null)
    {
        throw Error.ArgumentNull("request");
    }
    if (request.get_Properties().TryGetValue("MS_NextPageLink", out obj2))
    {
        return (obj2 as Uri);
    }
    return null;
}

 

 

上面是$format 和 $inlinecount參數的設置方法,$expand 參數我查到相關資料後再整理。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章