Wcf 为什么我的oData服务(实体框架)不允许导航属性

Wcf 为什么我的oData服务(实体框架)不允许导航属性,wcf,frameworks,entity,odata,Wcf,Frameworks,Entity,Odata,如果我在web项目中使用我的实体模型,我可以导航到1-*1-0.1 nav属性,但当我在oData服务中通过LinqPad加载完全相同的对象时,nav属性始终为空 …我做错什么了吗?…是否应该以某种方式启用它 如果我加载fiddler并运行查询http://odata.site.com/Service1.svc/usda_FOOD_DES1001/usda_ABBREV …它返回正确的结果 谢谢, 史蒂夫我问了自己同样的问题。我想知道为什么以下内容返回空集合: Customers.Where(c

如果我在web项目中使用我的实体模型,我可以导航到1-*1-0.1 nav属性,但当我在oData服务中通过LinqPad加载完全相同的对象时,nav属性始终为空

…我做错什么了吗?…是否应该以某种方式启用它

如果我加载fiddler并运行查询http://odata.site.com/Service1.svc/usda_FOOD_DES1001/usda_ABBREV

…它返回正确的结果

谢谢,
史蒂夫

我问了自己同样的问题。我想知道为什么以下内容返回空集合:

Customers.Where(c => c.ID == 1).Single().Orders
原因是,与实体框架的导航属性不同,当您访问OData实体的属性时,它不会自动返回数据源并检索任何尚未存在的数据。因此,当您从OData提要检索实体时,默认情况下它不包括链接的实体,因此对于一对多或多对多导航属性,您会得到一个空IEnumerable,对于单个实体导航属性,则会得到null

您希望将上述查询转换为:

http//odata.sample.com/MyODataFeed.svc/Customers1/Orders

这将返回所有订单,但它转换为在LINQPad中查看查询,请单击结果窗格上方的SQL按钮:

http//odata.sample.com/MyODataFeed.svc/Customers1

这是因为末尾的.Orders不在任何扩展方法内,因此不参与IQueryable的构造。因此,它不会反映在根据查询构造的URL中,也不会包含在结果集中

那么,您如何获得客户1的订单呢?您可以尝试使用以下查询解决此问题:

Customers.Where(c => c.ID == 1).Select(a => c.Orders)
这将导致.Orders属性包含在查询中。不幸的是,一个。选择。。。如果不将结果投影到匿名方法中,即不允许新建{…},并抛出NotSupportedException:不支持方法“Select”。真可惜。那么:

Customers.Where(c => c.ID == 1).Select(a => new { c.Orders })
它不会生成预期结果,而是执行以下查询:

Customers.Where(c => c.ID == 1).Select(a => c.Orders)
http//odata.sample.com/MyODataFeed.svc/Customers1?$expand=Orders&$select=Orders

我不明白为什么这不能翻译成/Customers1/Orders。在任何情况下,它都会将订单列表放在一个不需要的包装器类中,这可能会非常烦人,但它是有效的,而且它是我能够获得的最接近于检索导航属性内容的方法

我喜欢的方法是包括每个客户的所有订单,因此:

Customers.Expand("Orders").Where(c => c.ID == 1).Single().Orders
这将生成以下查询:

Customers.Where(c => c.ID == 1).Select(a => c.Orders)
http//odata.sample.com/MyODataFeed.svc/Customers1?$expand=订单


这是可行的,但缺点是包含了我们可能不需要的所有客户详细信息。此外,字符串的长度为.Expand。。。是有问题的-它的类型很弱,因此不会被编译器验证。当心拼写错误,不是所有的重构工具都会对它进行重构,查找该属性的所有用法不会在搜索结果中包含该字符串,等等。

来自的最新v4 Asp.Net oData支持 具有使用导航属性的更整洁的解决方案

要支持URL,请执行以下操作:

GET /Products(1)/Supplier
引述: 此处“供应商”是产品类型的导航属性。在这种情况下,供应商引用单个项目,但导航属性也可以返回集合一对多或多对多关系

要支持此请求,请将以下方法添加到ProductsController类:

关键参数是产品的关键。该方法返回相关实体(在本例中为供应商实例)。方法名和参数名都很重要。通常,如果导航属性名为“X”,则需要添加名为“GetX”的方法。该方法必须采用名为“key”的参数,该参数与父项的key的数据类型匹配


在关键参数中包含[FromOdataUri]属性也很重要。此属性告诉Web API在解析请求URI中的键时使用OData语法规则。

在LinqPad中加载是什么意思,能否将正在LinqPad中运行的查询发布?客户如何。Singlec=>c.ID==1。Selecta=>new{c.Orders}?我没有OData项目设置来测试它,但我认为这将返回一个IEnumerable,而不是嵌套在包装器中的IEnumerable。@JoelC:你不能使用.single的重载。。。有了OData,只有无参数的超负荷。单身,而且只有当它感觉让你。即使你可以…单身。。。返回一个不是IEnumerable的Customer类,因此不能对其使用任何LINQ运算符,例如.Select。。。。即使您可以使用use.Select…,您的代码仍将创建一个匿名类,其中包含一个名为Orders的属性,该属性将填充值c.Orders,因此您仍然拥有wra 高级船员。