如果我在web项目中使用我的实体模型,我可以导航到1- * 1-0.1 nav属性,但是当我加载确切的通过LinqPad在我的oData服务相同的对象导航属性始终为空为什么我的oData服务(实体框架)不允许导航属性
...我做错了什么?...应该启用某种方式吗?
如果我加载了小提琴手和运行查询http://odata.site.com/Service1.svc/usda_FOOD_DES(1001)/usda_ABBREV
...它返回正确的结果
谢谢你,史蒂夫
如果我在web项目中使用我的实体模型,我可以导航到1- * 1-0.1 nav属性,但是当我加载确切的通过LinqPad在我的oData服务相同的对象导航属性始终为空为什么我的oData服务(实体框架)不允许导航属性
...我做错了什么?...应该启用某种方式吗?
如果我加载了小提琴手和运行查询http://odata.site.com/Service1.svc/usda_FOOD_DES(1001)/usda_ABBREV
...它返回正确的结果
谢谢你,史蒂夫
我问自己同样的问题。我想知道为什么下面的返回一个空集:
Customers.Where(c => c.ID == 1).Single().Orders
的原因是,不像实体框架的导航性能,当你访问一个OData的实体的属性不会自动返回到数据源和检索任何尚未存在的数据。因此,当您从OData Feed中检索实体时,默认情况下它不包含链接的实体,因此您可以为一对多或多对多导航属性获取空的IEnumerable<T>
,或者对于单个实体导航属性为空。
你会期待上面的查询翻译成:
HTTP; // odata.sample.com/MyODataFeed.svc/Customers(1)/Orders
这将返回所有订单,而是将它转换为这个(看到LINQPad查询,请单击结果窗格上方的SQL按钮):
HTTP; // odata.sample.com/MyODataFeed.svc/Customers(1)
这是因为.Orders
最后不在任何扩展方法内,所以不参与IQueryable的构造。因此,它不反映在从查询构建的URL中,也不包含在结果集中。
那么如何才能得到客户1的订单?您可以尝试通过使用下面的查询解决此问题:
Customers.Where(c => c.ID == 1).Select(a => c.Orders)
这应该引起包括在查询中.Orders
财产。不幸的是,.Select(...)
没有将结果投影到匿名方法(即new { ... }
)是不允许的,并抛出NotSupportedException: The method 'Select' is not supported.
真是太遗憾了。那么,关于:
Customers.Where(c => c.ID == 1).Select(a => new { c.Orders })
不会产生预期的结果,而是执行以下查询:
HTTP; // odata.sample.com/MyODataFeed.svc/Customers(1) ?$ expand = Orders & $ select = Orders
我不明白为什么这不会被翻译成/ Customers(1)/ Orders。在任何情况下,它都会将订单列表放在一个不需要的包装类中,这可能非常烦人,但它起作用,并且它是我能够仅检索导航属性内容的最接近的工具。
我更喜欢的方法,是在包括所有与每个客户的订单,像这样:
Customers.Expand("Orders").Where(c => c.ID == 1).Single().Orders
这将产生以下查询:
HTTP; // odata.sample.com/ MyODataFeed.svc/Customers(1)?$ expand =订单
这样做有效,但有缺点,即包括我们可能不需要的所有客户详细信息。另外,.Expand(...)
的字符串有问题 - 它的输入很弱,所以它不会被编译器验证(注意拼写错误),并非所有的重构工具都会重构它,查找该属性的所有用法都不会在搜索结果中包含该字符串等。
'Customers.Single(c => c.ID == 1).Select(a => new {c.Orders})''怎么办?我没有OData项目设置来测试它,但我认为这将返回一个IEnumerable,而不是嵌套在一个包装器中的IEnumerable。 –
@JoelC:你不能在OData中使用'.Single(...)'的重载,只能使用无参数重载'.Single()'(并且只有当感觉就像让你)时。即使你可以,'.Single(...)'返回一个'Customer'类,它不是'IEnumerable
最新版本v4 Asp.Net o http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations oData支持 使用导航属性有一个更好的解决方案。
支持的网址:
GET /Products(1)/Supplier
报价: 这里的“供应商”是对产品类型的导航性能。在这种情况下,供应商引用单个项目,但导航属性也可以返回集合(一对多或多对多关系)。
为了支持此请求中,添加以下方法将ProductsController
类:
// GET /Products(1)/Supplier
public Supplier GetSupplier([FromODataUri] int key)
{
Product product = _context.Products.FirstOrDefault(p => p.ID == key);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product.Supplier;
}
的关键参数是该产品的密钥。该方法返回相关实体 - 在这种情况下为供应商实例。方法名称和参数名称都很重要。通常,如果导航属性名为“X”,则需要添加名为“GetX”的方法。该方法必须采用与父键的数据类型匹配的名为“key”的参数。
在关键参数中包含[FromOdataUri]
属性也很重要。此属性告诉Web API在解析请求URI中的密钥时使用OData语法规则。
你是什么意思“加载LinqPad”,你可以请你张贴在LinqPad中运行的查询吗? –