- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我创建了以下模型类
public class Car
{
public int Id {get;set;}
public string Name {get;set;}
public virtual ICollection<PartState> PartStates {get;set; }
}
public class PartState
{
public int Id {get;set;}
public string State {get;set;}
public int CarId {get;set;}
public virtual Car Car {get;set;}
public int PartId {get;set;}
public virtual Part Part {get;set;}
}
public class Part
{
public int Id {get;set;}
public string Name {get;set;}
}
和匹配的 DbContext
public class CarContext : DbContext
{
public DbSet<Car> Cars {get;set;}
public DbSet<PartState> PartStates {get;set;}
public DbSet<Part> Parts {get;set;}
}
并使用脚手架模板“Web API 2 OData Controller with Actions, using Entity Framework”创建了一个 WebApplication 以使其通过 odata 可用
我还创建了以下 webapi 配置:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Car>("Cars");
builder.EntitySet<PartState>("PartStates");
builder.EntitySet<Part>("Parts");
var edmModel = builder.GetEdmModel();
config.Routes.MapODataRoute("odata", "odata", edmModel);
}
}
我现在想将以下方法添加到我的汽车 Controller
// GET: odata/Cars(5)/Parts
[Queryable]
public IQueryable<Part> GetParts([FromODataUri] int key)
{
var parts = db.PartStates.Where(s => s.CarId == key).Select(s => s.Part).Distinct();
return parts;
}
并使用此 Url 检索数据:
http://localhost/odata/Cars(1)/Parts
但它不起作用,相反我得到以下错误:
{
"odata.error":{
"code":"","message":{
"lang":"en-US","value":"No HTTP resource was found that matches the request URI 'http://localhost/odata/Cars(1)/Parts'."
},"innererror":{
"message":"No routing convention was found to select an action for the OData path with template '~/entityset/key/unresolved'.","type":"","stacktrace":""
}
}
}
所以我的问题是,这可能吗?!
我尝试手动创建一个 Navigation 属性,并将其添加到 edm 模型中,虽然这确实解决了调用新方法的问题,但它也引入了新的错误。
编辑:
which id 确实尝试过这样手动添加:
var edmModel = (EdmModel)builder.GetEdmModel();
var carType = (EdmEntityType)edmModel.FindDeclaredType("Car");
var partType = (EdmEntityType)edmModel.FindDeclaredType("Part");
var partsProperty = new EdmNavigationPropertyInfo();
partsProperty.TargetMultiplicity = EdmMultiplicity.Many;
partsProperty.Target = partType;
partsProperty.ContainsTarget = false;
partsProperty.OnDelete = EdmOnDeleteAction.None;
partsProperty.Name = "Parts";
var carsProperty = new EdmNavigationPropertyInfo();
carsProperty.TargetMultiplicity = EdmMultiplicity.Many;
carsProperty.Target = carType;
carsProperty.ContainsTarget = false;
carsProperty.OnDelete = EdmOnDeleteAction.None;
carsProperty.Name = "Cars";
var nav = EdmNavigationProperty.CreateNavigationPropertyWithPartner(partsProperty, carsProperty);
carType.AddProperty(nav);
config.Routes.MapODataRoute("odata", "odata", edmModel);
虽然这允许我通过上面指定的 URL 调用上面指定的方法,但它给了我以下错误:
{
"odata.error":{
"code":"","message":{
"lang":"en-US","value":"An error has occurred."
},"innererror":{
"message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata=fullmetadata; charset=utf-8'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
"message":"The related entity set could not be found from the OData path. The related entity set is required to serialize the payload.","type":"System.Runtime.Serialization.SerializationException","stacktrace":" at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\r\n at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
}
}
}
}
最佳答案
您必须在 EntitySet 上调用“AddNavigationTarget”。假设您的命名空间是“MyNamespace”,然后将以下代码添加到您的 WebApiConfig.cs。这样,使用“Get: odata/Cars(1)/Parts”检索数据就可以了。
var cars = (EdmEntitySet)edmModel.EntityContainers().Single().FindEntitySet("Cars");
var parts = (EdmEntitySet)edmModel.EntityContainers().Single().FindEntitySet("Parts");
var carType = (EdmEntityType)edmModel.FindDeclaredType("MyNamespace.Car");
var partType = (EdmEntityType)edmModel.FindDeclaredType("MyNamespace.Part");
var partsProperty = new EdmNavigationPropertyInfo();
partsProperty.TargetMultiplicity = EdmMultiplicity.Many;
partsProperty.Target = partType;
partsProperty.ContainsTarget = false;
partsProperty.OnDelete = EdmOnDeleteAction.None;
partsProperty.Name = "Parts";
cars.AddNavigationTarget(carType.AddUnidirectionalNavigation(partsProperty), parts);
关于c# - 将自定义查询支持的导航属性添加到 ODataConventionModelBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23082927/
这要么是 super 直截了当,要么相对容易回答。我有以下代码来设置我的 OData 路由约定: // OData var builder = new ODataConventionModelBuil
情况 我创建了以下模型类 public class Car { public int Id {get;set;} public string Name {get;set;} p
我正在使用 ODataConventionModelBuilder 为 Web API OData 服务构建 Edm 模型,如下所示: ODataModelBuilder builder = new
除了将 CLR 类自动映射到 EDM 模型之外,ODataConventionModelBuilder 的优势或用例是什么? ? 它消除了哪些特定的痛苦?如果可能,请提供示例代码。 最佳答案 ODat
我在使用 Web API 2 和 OData v3 时遇到了一个奇怪的问题,特别是 ODataConventionModelBuilder .我的 WebApiConfig.cs 中有以下代码: //
我在 OData 看到过有 Edm 的文档类型 Date和 Time .目前在我的数据库中有很多 DATE字段在 EF 中表示为日期时间,因此 ODataConventionModelBuilder将
我有一个简单的entityframework poco对象 public partial class Location: Entity { [Key] public int Id {
我是一名优秀的程序员,十分优秀!