【发布时间】:2015-03-05 12:07:52
【问题描述】:
我有一个应用程序,它允许用户动态查询任何 OData 服务并将他们在网格内请求的特定列返回给他们。经过数周的研究,我最终使用Simple.OData.Client 来查询服务。为了取回数据,我有一个模型来定义需要做什么。以下是与我的问题相关的内容:
- BaseUrl(服务地址)
- ListName(要查询的表/列表)
- 列(列表)
- ODataColumnPath(我想要的数据的路径)
- ColumnDataType(返回/要转换为的数据类型)
- FriendlyName(易于使用的名称)
- CalculationType(枚举
None, Count, Sum, Min, Max)
现在ODataColumnPath 可以像“ProductName”一样简单,也可以像“Category/Product/Orders/OrderID”一样复杂,以返回单个字段或返回多个字段。当它返回许多值时,我会用它进行某种计算。
目前,我通过所有IEnumerable<IDictionary<string, object>>s 递归循环(while 循环)来创建DataTable,直到我得到我正在寻找的值。然后,我使用 XML 数据创建 DataTable 列,然后从循环中填充行。这种方法效果很好,但我不得不认为有更好的方法来做到这一点。
现在,当我在 LinqPad 中运行直接连接到 a Northwind odata service 的查询时,我得到了一个 IQueryable<Anonymous> 对象。
LinqPad -> 北风
Products.Select (x => new { x.ProductID, x.ProductName, x.Category.CategoryName })
请求网址
http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products()?$expand=Category&$select=ProductID,ProductName,Category/CategoryName
使用上面提到的 OData 库,我得到了与 IEnumerable<IDictionary<string, object>> 相同的数据
代码
ODataClient client = new ODataClient(new ODataClientSettings { UrlBase = "http://demos.telerik.com/kendo-ui/service/Northwind.svc/", OnTrace = (a, b) => { string.Format(a, b).Dump("Trace Event"); } });
var data = await client.For("Products").Expand("Category").Select("ProductID,ProductName,Category/CategoryName").FindEntriesAsync().Dump();
请求 URL(来自跟踪事件)
http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products?$expand=Category&$select=ProductID,ProductName,Category/CategoryName
现在,如果我指定一个强类型类,我会得到与 IQueryable 相同的结果(需要做一些额外的工作):
var strongly = (await client
.For<Product>()
.Expand(x => x.Category)
.Select(x => new { x.ProductID, x.ProductName, x.Category.CategoryName })
.FindEntriesAsync())
.Select(x => new { x.ProductID, x.ProductName, x.Category.CategoryName })
.Dump();
我想要返回的是匿名列表对象或动态对象。如果需要,我可以从那里应用我的计算。有没有办法动态定义一个类并将其传递给For<T>(...)静态方法?
尽管我花了数周时间研究这个主题并最终使用 Simple.OData.Client,但我愿意使用其他一些方法来获取我的数据。
【问题讨论】: