展开WCF数据服务(OData)的投影(选择)

Vac*_*ano 10 .net c# exception wcf-data-services odata

假设我有一个看起来像这样的OData查询(我的实际查询要复杂得多):

Orders.Select(z => new { z.SubOrder.Addresses,
                         z.SubOrder.Cost,
                         z.SubOrder.SubOrderId, 
                         z.Sequence});
Run Code Online (Sandbox Code Playgroud)

这很好用.除了Address对象上有一个子对象(StateRef).由于StateRef在State表上进行查找,因此返回null.

为了说明,下面是地址对象Address的外观示例:

Address:
    string         Street 1
    string         Street 2
    StateRef       PrimaryState
    string         City
    // ... 42 other string attributes not shown ...
Run Code Online (Sandbox Code Playgroud)

StateRef对象上有国家的名字,但也有一些其他重要的国家性质(也许州鸟?)

所以,我想知道的是,我现在必须为z.SubOrder.Addresses创建一个"子投影",其中包含所有46个属性,以便我可以访问该PrimaryState项目吗?(我希望不是)

除了更多的编码方式,它还意味着我必须使用匿名类型.这使我的映射必须手动(而不是使用AutoMapper).

那么我想要的是一种在投影中"扩展"StateRef的方法?

像这样的东西:

Orders.Select(z => new { z.SubOrder.Addresses.Expand("PrimaryState"),
                         z.SubOrder.Cost,        ^
                         z.SubOrder.SubOrderId,  |
                         z.Sequence});           |
                                                 |
// This is not allowed by the compiler ----------+
Run Code Online (Sandbox Code Playgroud)

试试这个就会出现这个错误:

无效的匿名类型成员声明符.必须使用成员分配,简单名称或成员访问声明匿名类型成员.

更新: 这是一个示例查询来说明我的问题:

Users.Take(10).Select(x=>new { x.Id, x.Reputation, x.Comments})
Run Code Online (Sandbox Code Playgroud)

针对" data.stackexchange.com/stackoverflow/atom " 运行它.您将看到Comments有一个返回null的Post对象.

我需要它来返回它内部的值.

注意:我知道我可以手动将所有这些输入到"子"投影中.请阅读上面我不想要的原因.

Iva*_*nov 7

当然可以这样做.要获得概念证明,请尝试执行以下操作:

var uri = new Uri( "http://data.stackexchange.com/stackoverflow/atom/Users()?$top=10&$expand=Comments/Post&$select=Id,Reputation,Comments/" );
entities.Execute<User>( uri, "GET", false ).Select( x => new { x.Id, x.Reputation, x.Comments } );
Run Code Online (Sandbox Code Playgroud)

expand的正确用法是这样的:

entities.Users.Expand( "Comments/Post" ).Take( 10 ).ToArray();
Run Code Online (Sandbox Code Playgroud)

我不知道为什么图书馆的作者决定不允许使用扩展和投影,但正如上面的概念证明所示,当然可以这样做.

如果您不介意接收整个用户并在此之后进行投影,则可以使用第二个示例.否则,您可以编写自己的帮助程序,它将从第一个示例生成URI,执行它们,然后添加投影.