为ODataConventionModelBuilder添加自定义查询支持的导航属性情况我创建了如下ModelclasspublicclassCar{publicintId{get;set;}publicstringName{获取;设置;}公共虚拟ICollectionPartStates{获取;设置;}}publicclassPartState{publicintId{get;set;}publicstringState{get;set;}publicintCarId{get;set;}publicvirtualCarCar{get;set;}publicintPartId{get;set;}publicvirtualPartPart{get;set;}}publicclassPart{publicintId{get;set;}publicstringName{get;}set;}}和匹配的DbContextpublicclassCarContext:DbContext{publicDbSetCars{get;set;}publicDbSetPartStates{get;set;}publicDbSetParts{get;set;}}并通过odata创建了一个WebApplication使用脚手架模板“WebAPI2ODataControllerwithActions,usingEntityFramework”我还创建了以下webapi配置:建造者.EntitySet(“Cars");builder.EntitySet("PartStates");builder.EntitySet("Parts");varedmModel=builder.GetEdmModel();config.我现在想将以下方法添加到我的汽车控制器//GET:odata/Cars(5)/Parts[Queryable]publicIQueryableGetParts([FromODataUri]intkey){varparts=db.PartStates.Where(s=>s.CarId==key).Select(s=>s.Part).Distinct();returnparts;}并使用此Url检索数据:http://localhost/odata/Cars(1)/Parts但它不起作用,而是出现以下错误:{"odata.error":{"code":"","message":{"lang":"en-US","value":"找不到与请求URI'http://localhost/odata/Cars(1)/Parts'."},"innererror":{"message":"没有找到路由约定来为带有模板'~/entityset/key/unresolved'的OData路径选择一个动作。","type":"","stacktrace":""}}}所以我的问题是,这有可能吗?!我尝试手动创建一个导航属性,并将其添加到edm模型中,而这确实解决了调用新方法的问题,它也引入了新的错误编辑:什么id尝试以这种方式手动添加它:varedmModel=(EdmModel)builder.GetEdmModel();varcarType=(EdmEntityType)edmModel.FindDeclaredType("汽车");varpartType=(EdmEntityType)edmModel.FindDeclaredType("零件");varpartsProperty=newEdmNavigationPropertyInfo();零件属性。TargetMultiplicity=EdmMultiplicity。许多;零件属性。目标=零件类型;零件属性。包含目标=假;零件属性。OnDelete=EdmOnDeleteAction。没有任何;carsProperty=newEdmNavigationPropertyInfo();carsProperty.TargetMultiplicity=EdmMultiplicity.Many;carsProperty.Target=carType;carsProperty.ContainsTarget=false;carsProperty.OnDelete=EdmOnDeleteAction.None;carsProperty.Name="汽车";varnav=EdmNavigationProperty.CreateNavigationPropertyWithPartner(partsProperty,carsProperty);carType.AddProperty(导航);config.Routes.MapODataRoute("odata","odata",edmModel);虽然这允许我通过上面指定的URL调用上面指定的方法,但它给了我以下错误:{“odata.error”:{“code":"","message":{"lang":"en-US","value":"发生错误。"},"innererror":{"message":"'ObjectContent`1'type无法序列化内容类型“application/json”的响应主体;odata=全元数据;charset=utf-8'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{"message":"无法从OData路径中找到相关实体集。序列化有效负载需要相关实体集。图,类型类型,ODataMessageWritermessageWriter,ODataSerializerContextwriteContext)rn在System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(类型类型,对象值,StreamwriteStream,HttpContent内容,HttpContentHeaderscontentHeaders)rn在System.Web.Http。OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Typetype,Objectvalue,StreamwriteStream,HttpContentcontent,TransportContexttransportContext,CancellationTokencancellationToken)rn---从先前抛出异常的位置开始的堆栈跟踪结束---rn在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNontask()rn你必须在EntitySet上调用“AddNavigationTarget”假设您的命名空间是“MyNamespace”,然后将以下代码添加到WebApiConfig.cs。这样,使用“Get:odata/Cars(1)/Parts”检索数据就可以了。varcars=(EdmEntitySet)edmModel.EntityContainers().Single().FindEntitySet("汽车");varparts=(EdmEntitySet)edmModel.EntityContainers().Single().FindEntitySet("零件");varcarType=(EdmEntityType)edmModel.FindDeclaredType("MyNamespace.Car");varpartType=(EdmEntityType)edmModel.FindDeclaredType("MyNamespace.Part");varpartsProperty=newEdmNavigationPropertyInfo();partsProperty.TargetMultiplicity=EdmMultiplicity.Many.Target=partType;partsProperty.ContainsTarget=false;partsProperty.OnDelete=EdmOnDeleteAction.None;partsProperty.Name="部件";cars.AddNavigationTarget(carType.AddUnidirectionalNavigation(partsProperty),零件);进一步考虑@FengZhao的回答,为了使urlodata/Cars正常工作,您还需要向实体集链接构建器注册导航属性链接构建器。varcars=(EdmEntitySet)edmModel.EntityContainers().Single().FindEntitySet("汽车");varparts=(EdmEntitySet)edmModel.EntityContainers().Single().FindEntitySet("零件");varcarType=(EdmEntityType)edmModel.FindDeclaredType("MyNamespace.Car");varpartType=(EdmEntityType)edmModel.FindDeclaredType("MyNamespace.Part");varpartsProperty=newEdmNavigationPropertyInfo();partsProperty.TargetMultiplicity=EdmMultiplicity.Many;partsProperty.Target=partType;partsProperty.ContainsTarget=false;partsProperty.OnDelete=EdmOnDeleteAction.None;partsProperty.Name="部件";varnavigationProperty=carType.AddUnidirectionalNavigation(partsProperty);cars.AddNavigationTarget(导航属性,零件);varlinkBuilder=edmModel.GetEntitySetLinkBuilder(汽车);linkBuilder.AddNavigationPropertyLinkBuilder(navigationProperty,newNavigationLinkBuilder((context,property)=>context.GenerateNavigationPropertyLink(property,false),true));网页Api无法根据任何已注册的URI模板解析您的URL使用路由调试器来解决此问题。http://blogs.msdn.com/b/webdev/archive/2013/04/04/debugging-asp-net-web-api-with-route-debugger.aspx我相信我们的问题是你正在通过url的id参数试图让它更清楚。以上就是C#学习教程:为ODataConventionModelBuilder分享的所有内容添加自定义查询支持的导航属性。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注—config.Routes.MapHttpRoute("DefaultInternalApi","api/{controller}/{objectType}/{Id}/{关系}",默认值:新{Id=System.Web.Http.RouteParameter.Optional,});本文整理自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
