博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.net core 学习笔记 ( OData )
阅读量:5859 次
发布时间:2019-06-19

本文共 6106 字,大约阅读时间需要 20 分钟。

2019-05-18 更新 : 

目前遇到的问题 

odata 团队非常的不给力,虽然我都用了好多年了,但是越用越少. 它的维护实在太差了。

很多好的功能都是因为 bug 而用不上. 

1. 

/api/orders?$filter=stringList/any(v:v eq 'a')

stringList 是一个 json 来的, 使用 any 可以进行 filter, 虽然它不是在 sql 层面上做 filter 但也很不错了。

可是呢,如果 stringList 是 empty array 那样就会报错了. 

而 /$count gt 0 有 bug 不能用.

应对方式,  json 就不要做 filter

 

2.

complex type $select 不能用. bug ! 

应对 : 不要用 complex type 改用 1-1 

 

3. 

继承 + $expand 

应对 : 不要用继承

 

从前用 odata 做 restful GET POST DELETE PUT,用久了最后剩下 GET, 其余的全部用 web api 

虽然 odata 很多问题, dto 也支持到很差基本不用. 

但是任然比 graphql 好用. 希望有天这 2 个工具都越来越好呗. 

 

 

 

2018-12-10 更新 : 

从前我都是把 entity 直接用于 odata 曝露 api 给程序用. 

如果这个程序是我们自己写的前端,这样的方式非常好,因为就好比前端可以直接对数据库每一个表做操作。

但是呢,如果这个程序是外部的,那么就可能不应该直接把 entity 曝露出去了。

这时就会有个 dto 的概念来了.

上层点看,就是对于这些外人,他们依然可以使用 odata 访问数据,也可以 restful ,但是呢,他们看到的 entity 和我们数据来真正的 entity 是不同的。

这个概念和数据库做 view 表是一样的. 

这时比较大的问题就是映射了. 因为用户操作的表可能并不存在,或者是多表联合而成. 

如果用过 automapper 的可以尝试   useAsDataSource

return Ok(Db.Categories.UseAsDataSource().For
());

automapper 会帮我们对应好, 不过目前测试 expand 是会报错的... 我目前是没有这个需要. 希望要用到的时候一切正常..

虽然我没有需要在 get 的情况下使用 Dto 概念. 

但是在 post put delete 时却是需要的,我个人的感觉是如果是内部用的 api 就不要使用 restful, 提供给外部的 api 就用. 类似 facebook 的 graphapi 那样就不错.

那 post put 的时候就得使用 odata action 了

action 遇到最大的问题是, parameters 每次要定义. 如果我们使用 dto 基本上可以用 [FormBody] 无需定义, 有一个前提是 postdata 不可以有继承 @odata.type 这种东西, 也不可以是 entity (必须是 dto)

那么如果真的遇到要继承,那就只能写 parameters 了。

builder.EntitySet
("Users");var a = builder.EntityType
().Collection.Action("CreateUser");a.Parameter
("user");a.Namespace = "Rpc"; // Namespace 是必须的,而且不要定义在全局哦. 不然你 get data 的时候, 派生类会变成 @odata.type = "#Namespace.", 这是不对的,应该是 @odata.type = "#YourEntityNamespace." 才对.[HttpPost]public IActionResult CreateUser(ODataActionParameters parameters){
// Model.State.IsValid // valid parametes only var user = (UserDto)parameters["user"]; var v = TryValidateModel(user); //valid real post data var error = ModelState; //get error return Ok();}// post data { user : { "Id": 1, "password": "", "characters": [ { "@odata.type": "#odata.Models.AdminDto", "Id": 1, "name": "", "userId": 1, "age": 11 } ] } }

 

 

 

和 asp.net odata 区别不大. 用法依旧. 

定义 EdmModel 

public static class ODataConfig{    public static IEdmModel GetEdmModel(IServiceProvider servicePrivider)    {        var builder = new ODataConventionModelBuilder(servicePrivider);        /*             对应 route :            GET : /odata/products            GET : /odata/products(key)            POST : /odata/products             PUT : /odata/products(key)            DELETE : /odata/products(key)        */        builder.EntitySet
("Products"); // POST /odata/products/changeSort var productChangeSort = builder.EntityType
().Collection.Action("changeSort"); productChangeSort.Returns
(); // POST /odata/products(key)/doSomething var sample1 = builder.EntityType
().Action("doSomething"); sample1.Returns
();

          // GET /odata/products/getSomething

          var sample2 = builder.EntityType<Product>().Collection.Function("getSomething");
          sample2.ReturnsCollectionFromEntitySet<Product>("Products");

return builder.GetEdmModel();    }}

普通的 get,post,put,delete 和 RPC get 和 post 

然后在 UseMvc 添加上 routing

app.UseMvc(builder =>{    builder.MapRoute(        name: "default",        template: "{controller=Home}/{action=Index}/{id?}");    builder.Select().Expand().Filter().OrderBy().MaxTop(null).Count();    builder.MapODataServiceRoute("odata", "odata", ODataConfig.GetEdmModel(app.ApplicationServices));});

odata 有 default routing 匹配的概念,就好像第一个 code 图的 path 就是 default 的对应. 

因为使用的是 default routing 所以不需要添加 [ODataRoute] 标签, 同时也无法使用 [ApiController], 因为 apicontroller 依赖 route 标签...

所以我们必须使用 [FromQuery] [FromBody] binding data. 

builder.EntitySet<Product>("Products"); 里头的 "Products" 对应了 "ProductsController" 

get,put,post,delete 是通过方法名字的前面几个字来匹配的. 

builder.EntityType<Product>().Collection.Action("changeSort") 的 "changeSort" 对应的是 "changeSort" 方法名 

如果你使用 ODataRoute 的话,那么就不看方法名字,转而看 ODataRoute 来对应. 同时需要写上 httpmethod 标签来做匹配. 

建议使用自动匹配, 方法名字 unique 就行了, 还有 url 是不区分大小写的. action 也不一定要写上 namespace, 不写也是可以 ok 的哦.

如果是手动调用的话,还是区分大小写和使用 namespace 比较好,看来 odata 在处理 request 的时候帮我们做了些事儿,所以才那么方便. 

var request = new ODataUriParser(Request.GetModel(), "http://192.168.1.152:61547/api", "http://192.168.1.152:61547/api/Users/RPC.Me?$expand=characters") { Resolver = new ODataUriResolver { EnableCaseInsensitive = true } }.ParseUri(); var uri = request.BuildUri(ODataUrlKeyDelimiter.Parentheses);

还有 build uri 和之前有点不同了. 

public class ChangeSortData    {        public int aSort { get; set; }        public int bSort { get; set; }    }    public class ProductsController : ODataController    {        private DB Db { get; set; }        public ProductsController(DB db)        {            Db = db;        }        [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.Count | AllowedQueryOptions.Expand, MaxExpansionDepth = 0)]        public IActionResult Get(ODataQueryOptions
queryOptions) { return Ok(Db.Products); } public IActionResult Post([FromBody] Product resource) { return Ok("ok"); } public IActionResult Put(int key, [FromBody] Product resource) { return Ok("ok"); } public IActionResult Delete(int key) { return Ok("ok"); } public IActionResult ChangeSort([FromBody] ChangeSortData data) { return Ok("ok"); } public IActionResult DoSomething(int key) { return Ok("ok"); } [HttpGet] //由于没有自动匹配了,所以我们需要表达式 get 请求,这样才匹配的到 [ODataRoute("products/getsomething")] public IActionResult WhatEver() { return Ok("ok"); } }

 

转载于:https://www.cnblogs.com/keatkeat/p/9297826.html

你可能感兴趣的文章
自动取词,并提取大文本的关键字
查看>>
IOS ARC 和 非ARC 之间的转换方法
查看>>
Android 编译出错解决
查看>>
Docker使用阿里云镜像加速
查看>>
正则匹配记录包含不包含
查看>>
Tomcat安装及eclipse配置
查看>>
运用myeclipse导入Java项目后,在项目文件上出现一个红色的"!"
查看>>
A公司商户检索底层架构设计【上篇】
查看>>
Openstack安装(2)——glance安装与配置
查看>>
spring如何处理xml配置文件
查看>>
iOS--The request was denied by service delegate (SBMainWorkspace) for reason:
查看>>
CentOS安装rar、7z压缩
查看>>
mysql 建表时添加注释以及查看注释
查看>>
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
查看>>
AI 考拉技术分享会--API 接口与 Typescript Interface
查看>>
.net core webapi 转成数据流
查看>>
SVG.js - 用于SVG操作和产生动画的一个轻量级js库
查看>>
Web前端团队开发规范文档
查看>>
spring 常用工具包
查看>>
记录技术(实时服务器)
查看>>