Breeze WebAPI: How to combine QueryResult with ODataQueryOptions to return inlineCount

北城余情 提交于 2019-12-10 11:24:20

问题


I tried different ways of loading a list of items using breeze and the API Controller, using filters (partly using a custom object and another part using ODataQueryOptions), but none of them turn out to be really successful.

Test code in javascript:

    function test() {
        EntityQuery
            .from("Products")
            /*
            .withParameters({
                filters: [
                { column: "Name", value: "12" }
            ]})
            */
            .orderBy("Name desc")
            .skip(30)
            .take(15)
            .inlineCount(true)
            .using(manager)
            .execute()
            .then(success)
            .fail(fail);

        function success(data) {
            console.log(data.products);
            console.log(data.inlineCount);
        }
        function fail(error) {
            console.log(error.message);
        }
    };
    test();

Ideally I would like to accomplish this using something like this:

public IQueryable<Product> Products([FromUri] FilterObject[] filters, ODataQueryOptions odataQueryOptions)
        {
            var result = DummyData.GetProducts();            
            //var totalRowCount = result.Count();

            return result;
        }

The data will be filtered somewhere else (using nHibernate), I removed the part used to parse filters etc. However, this will never work since the other layer will return the total row count.

So I tried to replace it with :

public QueryResult Products([FromUri] FilterObject[] filters, ODataQueryOptions odataQueryOptions)
{
...
        return new QueryResult
            {
                InlineCount = totalRowCount,
                Results = result
            };
}

This throws an error: Cannot create an EDM model as the action 'Products' on controller 'Product' has a return type 'Breeze.WebApi.QueryResult' that does not implement IEnumerable.

The error disappears when removing the ODataQueryOptions variable. A search didn't give me valuable feedback.

I tried this:

public PageResult<Product> Products([FromUri] FilterObject[] filters, ODataQueryOptions odataQueryOptions)
{
....
    return new PageResult<Product>(result, null, totalRowCount);  
}

This won't throw an error. When opening the returned data object contains an inlineCount parameter with value being undefined, the actual data is in the first item in a nested results array (Count, Items and NextPageLink).

Is this the only way to get this working?

This can be reproduced in the NoDb sample of breeze, by adding ODataQueryOptions as parameter to the TodoLists method:

    // GET ~/breeze/BreezeTodo/TodoList
    [HttpGet]
    public IQueryable<TodoList> TodoLists(ODataQueryOptions odataQueryOptions)
    //public IQueryable<TodoList> TodoLists()
    {
        var result = _repository.TodoLists;
        result = result.OrderByDescending(t => t.TodoListId);

        return result;
    }

Using

        return breeze.EntityQuery
            .from("TodoLists")
            .inlineCount(true)
            .skip(0).take(15)
            .using(manager).execute()
            .then(getSucceeded)
            .fail(getFailed);

The request looks like this:

GET /breeze/Todo/TodoLists?$top=15&$inlinecount=allpages HTTP/1.1

The fiddle result with the ODataQueryOptions:

[{"$id":"1","$type":"NoDb.Models.TodoList, NoDb","TodoListId":1,"Title":"Before work","Todos":[{"$id":"2","$type":"NoDb.Models.TodoItem, NoDb","TodoItemId":1,"Title":"Make coffee","IsDone":false,"TodoListId":1,"TodoList":{"$ref":"1"}},{"$id":"3","$type":"NoDb.Models.TodoItem, NoDb","TodoItemId":2,"Title":"Turn heater off","IsDone":false,"TodoListId":1,"TodoList":{"$ref":"1"}}]}]

And without:

{"$id":"1","$type":"Breeze.WebApi.QueryResult, Breeze.WebApi","Results":[{"$id":"2","$type":"NoDb.Models.TodoList, NoDb","TodoListId":1,"Title":"Before work","Todos":[{"$id":"3","$type":"NoDb.Models.TodoItem, NoDb","TodoItemId":1,"Title":"Make coffee","IsDone":false,"TodoListId":1,"TodoList":{"$ref":"2"}},{"$id":"4","$type":"NoDb.Models.TodoItem, NoDb","TodoItemId":2,"Title":"Turn heater off","IsDone":false,"TodoListId":1,"TodoList":{"$ref":"2"}}]}],"InlineCount":1}

回答1:


The solution appears to be:

public QueryResult TodoLists(ODataQueryOptions<TodoList> odataQueryOptions)

Fiddler:

Request:

GET /breeze/Todo/TodoLists?$top=15&$inlinecount=allpages HTTP/1.1

Response:

{"$id":"1","$type":"Breeze.WebApi.QueryResult, Breeze.WebApi","Results":[{"$id":"2","$type":"NoDb.Models.TodoList, NoDb","TodoListId":1,"Title":"Before work","Todos":[{"$id":"3","$type":"NoDb.Models.TodoItem, NoDb","TodoItemId":1,"Title":"Make coffee","IsDone":false,"TodoListId":1,"TodoList":{"$ref":"2"}},{"$id":"4","$type":"NoDb.Models.TodoItem, NoDb","TodoItemId":2,"Title":"Turn heater off","IsDone":false,"TodoListId":1,"TodoList":{"$ref":"2"}}]}],"InlineCount":1}


来源:https://stackoverflow.com/questions/18878035/breeze-webapi-how-to-combine-queryresult-with-odataqueryoptions-to-return-inlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!