12/08/2018, 14:15

Query trong web api odata

Trong bài viết này mình cùng các bạn tìm hiểu về những query mà có thể thực hiện từ client sử dụng web odata api. Đây chính là điểm mạnh nhất và sự khác biệt lớn nhất mà mình thấy giữa web odata api và web api thông thường. Chúng ta sẽ tạo một project nhỏ về web odata api để demo và tìm hiểu những ...

Trong bài viết này mình cùng các bạn tìm hiểu về những query mà có thể thực hiện từ client sử dụng web odata api. Đây chính là điểm mạnh nhất và sự khác biệt lớn nhất mà mình thấy giữa web odata api và web api thông thường. Chúng ta sẽ tạo một project nhỏ về web odata api để demo và tìm hiểu những câu query nhé.

Tạo database

CREATE DATABASE WebApiOdataTest

CREATE TABLE Category (Id int NOT NULL, Name nvarchar(100) NOT NULL, [Description] nvarchar(255), PRIMARY KEY (Id))

CREATE TABLE Product (Id int NOT NULL, Name nvarchar(100) NOT NULL, Price float, CategoryId int, PRIMARY KEY (id),
FOREIGN KEY (CategoryId) REFERENCES Category(Id))

Tạo project

Từ visual studio, chọn new Project -> ASP.NET Web Application -> MVC empty project và chọn Web API.

create project.png

Tiếp theo, ta sẽ generate ra các model từ database vừa tạo bằng cách tạo ra 1 Entity Data Model.

Right click vào thư mục model, chọn new item -> ADO.NET entity data model, đặt tên là EntitiesModel.

Sau đó chọn connectionString và chọn CodeFirstFromDatabase. Chọn các bảng và Finish.

codefirst_select.png

Bây giờ ta đã có các model. Bước tiếp theo là cài đặt web odata v4 package

Right click vào project và chọn Manage Nuget Packages..., tìm Microsoft.AspNet.OData for OData v4.0, install.

nuget odata package.png

Tạo Product Controller kế thừa từ ODataController

using System.Linq;
using System.Web.Http;
using System.Web.OData;
using WebODataV4.Models;

namespace WebODataV4.Controllers
{
    public class ProductController : ODataController
    {
        readonly EntitiesModel _db = new EntitiesModel();

        [EnableQuery(PageSize = 20)]
        public IHttpActionResult Get()
        {
            return Ok(_db.Product.AsQueryable());
        }

        public IHttpActionResult Get([FromODataUri] int key)
        {
            return Ok(_db.Product.SingleOrDefault(t => t.Id == key));
        }

        protected override void Dispose(bool disposing)
        {
            _db.Dispose();
            base.Dispose(disposing);
        }
    }
}

Tiếp theo config route cho Odata service này. Đơn giản như bên dưới.

using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
using WebODataV4.Models;

namespace WebODataV4
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.MapODataServiceRoute("odata", "odata", model: GetModel());

            /* now the default setting for WebAPI OData is:
            client can’t apply $count, $orderby, $select, $top, $expand, $filter in the query, query
            like localhostodataCustomers?$orderby=Name will failed as BadRequest,
            because all properties are not sort-able by default, this is a breaking change in 6.0.0
            So, we now need to enable OData Model Bound Attributes
            */
            config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
        }

        public static Microsoft.OData.Edm.IEdmModel GetModel()
        {
            ODataModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntitySet<Product>("Product");
            builder.EntitySet<Category>("Category");

            return builder.GetEdmModel();
        }
    }
}

Bây giờ web service api odata của chúng ta đã có thể sử dụng được. Giờ chỉ cần thêm dữ liệu và test thôi. Hãy dùng POSTMAN và thử test nhé

QUERY

lấy tất cả product: http://localhost:1281/odata/Product

1.png

lấy 1 product: http://localhost:1281/odata/Product(1)

2.png

chỉ lấy thuộc tính Id và name của product http://localhost:1281/odata/Product?$select=Id,Name

3.png

lấy thêm cả object category mà product thuộc về http://localhost:1281/odata/Product?&$expand=Category

4.png

chỉ lấy 2 product đầu tiên http://localhost:1281/odata/Product?$top=2

5.png

chỉ lấy 3 products, bỏ qua 2 product đầu tiên http://localhost:1281/odata/Product?$top=3&$skip=2

6.png

sắp xếp list product trả về theo tên http://localhost:1281/odata/Product?$orderby=Name

7.png

lọc product by Name http://localhost:1281/odata/Product?$filter=Name eq 'No family'

8.png

Đếm số lượng bản ghi. chỉ cần thêm option count=true‘http://localhost:1281/odata/Product?count=true `http://localhost:1281/odata/Product?count=truehttp://localhost:1281/odata/Product?count=true`

9.png

Những option query này đương nhiên có thể dùng kết hợp với nhau như: http://localhost:1281/odata/Product?$select=Id,Name&$expand=Category http://localhost:1281/odata/Product?$top=3&$skip=2&$orderby=Name

Như vậy với một số lượng dòng code rất ít và đơn giản, nhưng với web odata api, bạn có thể lấy được dữ liệu theo cách mình muốn một cách rất thuận tiện và dễ dàng nhất.

0