使用OData进行查询而不公开ORM模型? [英] Query with OData without exposing ORM models?

查看:259
本文介绍了使用OData进行查询而不公开ORM模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Web api 2项目中,如果我想使用OData库(看起来很棒并且很诱人)对某些属性进行查询,这将迫使客户端知道我的数据库模型的确切属性。这是一个好习惯吗?有办法避免这种分离吗?

In my web api 2 project, if I want to use OData library (which looks awesome and very tempting) for queries over some properties, that would force the client side to know the exact properties of my database models. Is this a good practice? Is there a way to avoid this decouple?

对于以下模型:

public class LetterEntity
    {
        public int Id {get; set;}

        public string Title {get; set;}

        public string Content {get; set;}

        public string Source {get; set;}

        public DateTime SendingTime {get; set;} 

        public string AnotherWierdString {get; set;
        ...
    }

    public class LetterDTO
    {
        public int Id {get; set;}

        public string Title {get; set;}

        public string LetterContent {get; set;}

        public string Source {get; set;}

        public DateTime SendingTime {get; set;} 
    }

    public class LetterInsideFolderDTO 
    {
        public string Title {get; set;}

        public string Source {get; set;}
    }


public class LettersController : ApiController
{
    // In this approach method, I hate the fact that a LetterEntity must be used for the query.
    [HttpGet]
    [Route("api/letters")]
    [EnableQuery]
    public IQueryable<LetterInsideFolderDTO> Get(ODataQueryOptions<LetterEntity> query) 
    { 
        IQueryable<Letter> letters = db.Letters;

        var afterQuery = query.ApplyTo(letters)

        IQueryable<LetterInsideFolderDTO> dtos = afterQuery.ProjectTo<LetterInsideFolderDTO>(afterQuery)

        return dtos;
    }


    // Is there a way to do something like the following?:  
    [HttpGet]
    [Route("api/letters")]
    [EnableQuery]
    public IQueryable<LetterInsideFolderDTO> Get(ODataQueryOptions<LetterDTO> query) 
    { 
        IQueryable<Letter> letters = db.Letters;

        // Convert the query to work on the entities somehow? Should I use a mapping between LetterDTO to LetterEntity?
        // I only have a map from LetterEntity to LetterDTO
        var afterQuery = query.ApplyTo(letters)

        IQueryable<LetterInsideFolderDTO> dtos = afterQuery.ProjectTo<LetterInsideFolderDTO>(afterQuery)

        return dtos;
    }
}

由于目前我选择实体直接在客户端查询中建立模型,客户端与服务器之间存在很强的耦合。
例如,如果我要查询并获取 Content 字段内所有带有 abc的字母,我需要路由至以下内容:

Because of the fact that at the moment I take Entity model directly in the clients query, there is a strong coupling between clients and server. For example if i want to query and get all the letters that has "abc" inside the Content field, I need to route to the following:

api/letters/?$filter=contains(Content,'abc')

如果明天我决定将该属性从 Content更改为 LetterContent,则所有客户代码都会被破坏。

If tomorrow I decide to change that property from "Content" to "LetterContent" all clients code will be broken.

我如何超越它?

谢谢!

编辑:

请给我一个具体的例子,
我还不知道HATEOAS是什么(如果这可以帮助我解决此问题),
文档服务如何帮助我?如果我决定更改我的EDM模型,它仍然会迫使客户更改代码?

Please give me a concrete example, I don't understand yet what HATEOAS are (if that helps me solve this issue), How can documentation service help me? It'll still force clients to change their code if I decide to change my EDM models?

推荐答案



如果我想使用OData库(看起来很棒并且很诱人)来查询某些属性,这将迫使客户端知道我的数据库模型的确切属性。这是一个好习惯吗?

if I want to use OData library (which looks awesome and very tempting) for queries over some properties, that would force the client side to know the exact properties of my database models. Is this a good practice?


这取决于您的意思是会迫使客户一边知道确切的属性。有两种方法:

It depends on what do you mean by "would force the client side to know the exact properties". There are two ways:


  1. 使用由datasvcutil制造的自动生成的代理。确实,这将迫使客户端知道确切的属性,因为它们是在客户端进行硬编码的。当服务器端改变时,客户端将被破坏-客户端/服务器紧密耦合。通常这很不好,但是通常如果您需要快速完成工作-datasvcutil是您的工具。

  1. Use auto-generated proxies made by datasvcutil. Indeed, that would force the client side to know the exact properties since they are hard-coded in client-side. When server side is changed client would be broken - client/server are tightly coupled. In general it's bad, but usually if you need smth to get done quickly - datasvcutil is your tool.

了解您的客户端以读取服务文档,以便他可以动态决定他可以查询哪些资源。您拥有所有功能-服务文档,元数据。

Learn your client to read service document, so that he could dynamically decide what resources he may query. You have everything for it - service document, metadata.

请记住,OData是基于REST体系结构构建的,该体系结构具有一组通过一组约束获得的优势。约束条件包括可寻址性和HATEOAS。

Remember that OData is built on REST architecture which has a set of advantages that are achieved via set of constraints. Several of constraints are Addressability and HATEOAS.

可寻址性意味着每个资源都必须具有其地址。

Addressability means that each resource must have its address.

HATEOAS 意味着,在任何给定时刻,基于超媒体的客户(代表当前资源)必须拥有他需要确定的所有信息下一步要去哪里。

HATEOAS means that in any given moment, client, based on hypermedia in representation of current resource, must have all the information he needs to decide where to transit next.

要知道要去哪里,客户端必须

In order to know where to transit client must


  1. 知道如何在数据流中查找他可能会经过的资源(URL)。就像您获取带有文本和URL的数据一样,客户必须知道如何查找URL。 URL可能具有不同的含义-例如用于CRUD操作的多个URL。

  1. Know how to find resources(URL's) in the stream of data where he may transit. Like you get data with text and URL's - client must know how to find URL's. URL may have different meanings - like several URL's for CRUD operations.

获取包含资源的数据。通常,客户必须知道如何开始查询服务

Get that data with resources. In general client must know how to start querying service

第一点是通过配置文件解决的。配置文件-允许客户了解与资源表示形式关联的其他语义( https://tools.ietf.org/ html / rfc6906 )。考虑一下它的OData文档。对于OData,您的客户端必须知道OData中的数据是通过Atom或Json格式表示的。客户必须了解构造对OData服务的查询,获取特定记录等的原理。

First point is resolved via profiles. Profile - allows clients to learn about additional semantic associated with the resource representation (https://tools.ietf.org/html/rfc6906). Consider it OData documentation. In case of OData your client must know that data in OData is represented via Atom or Json formats. Client must know principles of constructing queries to OData service, of getting specific record and so forth.

如果客户调用OData根地址-类似于... OData.svc,他将获得他可以查询的所有资源的清单(服务文档)。这就是解决第二点的方法。

If client calls OData root address - smth like ...OData.svc, he would get list of all resources that he can query(service document). That is how second point is resolved.

您可能会更进一步,并通过$ metadata后缀获取元数据。这将为您提供资源的所有属性。

You may come further and get metadata via $metadata suffix. That would give you all properties of resources.

这篇关于使用OData进行查询而不公开ORM模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆