OData 和 Cosmos DB
Posted
技术标签:
【中文标题】OData 和 Cosmos DB【英文标题】:OData and Cosmos DB 【发布时间】:2019-06-27 04:58:21 【问题描述】:我希望在我正在开发的 ASP.NET Core 应用程序中实现 OData v4 作为查询工具,我们的支持持久性存储是 Cosmos DB。到目前为止,我还没有想出一种方法来使 OData 查询针对 DocumentQuery IQueryable 接口运行而不会遇到某种异常或错误。
我想知道是否有一种“干净”的方法可以针对 Cosmos Document DB(而不是 Table API)使用 OData,如果有,怎么做?到目前为止,我发现的只是一个使用 Framework v4.6 的非官方库,但没有任何官方的,而且我发现的有关实现 OData 的所有文档几乎都是针对 Entity Framework 或内存数据存储运行的。
【问题讨论】:
您编写连接到任何数据存储的动态 OData 服务。有一个例子:***.com/questions/29981931/… 直接使用 SQL Server 没有 EF 也没有什么特别的。您可以将 SQL 调用替换为 CosmosDB 调用。 嗯...我一开始对 OData 不是很熟悉,所以这需要一些时间来解压。我不太确定所有过滤、选择等在哪里进行。我的理解是,您的 odata 端点应该只返回一个 IQueryable,它会处理其余部分,而您发送给我的内容似乎是在代码中执行的。我在这里缺少什么吗? 所以我遇到的第一个问题是 Request.ODataFeature() 调用返回一个未初始化的对象。 您希望看到什么?有示例代码吗? 另外,请记住,由 ASP.NET/WebApi 提出的 OData 模型 (Edm) 是结构化的实体/属性模型(检查 odata.github.io/WebApi),那么如何从非结构化/分层JSON (CosmosDB) 到表格 OData Edm 模型(超出任何技术细节)?顺便说一句,这就是为什么 CosmosDB 只支持表 API 的 OData 【参考方案1】:我知道这并不是对我的问题最有洞察力的答案,但这里的正确答案真的是不要尝试这样做。如果您曾经处于有人要求您尝试将两种实际上并没有一起使用的技术强行结合在一起的位置,请拒绝并处理后果。
【讨论】:
那么这个呢? devblogs.microsoft.com/odata/…【参考方案2】:如果您使用的是 SQL api,OData 与 Cosmos 的集成并不难,并且您只需要 $orderby、$top 和 $skip 等基本内容。这是生成正确 SQL 的问题。
如果你需要更多,那就更难了。无论如何,我用这个NuGet lib 做了一些简单的测试。至少从我的简单测试来看,它似乎有效。
var oDataToSqlTranslator = new ODataToSqlTranslator(new SQLQueryFormatter());
var select = oDataToSqlTranslator.Translate(odataQueryOptions, TranslateOptions.SELECT_CLAUSE);
var where = oDataToSqlTranslator.Translate(odataQueryOptions, TranslateOptions.WHERE_CLAUSE);
var order = oDataToSqlTranslator.Translate(odataQueryOptions, TranslateOptions.ORDERBY_CLAUSE);
var top = oDataToSqlTranslator.Translate(odataQueryOptions, TranslateOptions.TOP_CLAUSE);
var all = oDataToSqlTranslator.Translate(odataQueryOptions, TranslateOptions.ALL);
log.LogInformation("SQL select => " + select);
log.LogInformation("SQL where => " + where);
log.LogInformation("SQL order => " + order);
log.LogInformation("SQL all => " + all);
给定这个 URL 作为输入:
http://localhost:7071/api/v1/invoices/customer/20?$top=2&$select=CustomerId&$filter=InvoiceNumber eq 'xxx'&orderby=brand
日志显示:
SQL select => SELECT c.CustomerId FROM c
SQL where => WHERE c.InvoiceNumber = 'xxx'
SQL order => ORDER BY c.InvoiceNumber ASC
SQL all => SELECT TOP 2 c.CustomerId FROM c WHERE c.InvoiceNumber = 'xxx' ORDER BY c.InvoiceNumber ASC
【讨论】:
【参考方案3】:怎么样 - 将 OData 转换为 SQL,然后在 CosmosDB 上执行它 https://github.com/Azure/azure-odata-sql-js
【讨论】:
以上是关于OData 和 Cosmos DB的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft.AspNet.WebApi.OData 与 Microsoft.Data.OData 和 Microsoft.AspNet.OData 有啥区别?