我在Asp.Net Web Api应用程序中有一个允许OData查询的ODataController。我只允许读取,而不是更新。我没有直接暴露数据模型,而是创建了一组DTO。 DTO上的属性名称不一定与EF模型上的属性匹配。当我尝试对EF模型使用OData查询时,这会导致问题。我已经看过StackOverflow关于这个主题的其他帖子,但似乎没有人解决这个问题。
这就是我现在所拥有的:
public IQueryable<Customer> GetCustomer(ODataQueryOptions<Customer> query)
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Customer>("Customers");
builder.EntitySet<RECORD>("Records");
builder.Namespace = "MyDataService.Models";
var opts = new ODataQueryOptions<RECORD>(new ODataQueryContext(builder.GetEdmModel(), typeof(RECORD)), this.ActionContext.Request);
var records = (IQueryable<RECORD>)opts.ApplyTo(db.RECORDS);
return ConvertToCustomerList(records);
}
这一直有效,直到我引用选择或过滤器中的特定字段。一旦我在OData查询中引用了一个字段,我就会得到一个类似于 - Could not find a property named 'LastName' on type 'MyDataService.Models.RECORD
的ODataException。这是因为EF属性具有不同的命名约定。在这种情况下,它应该使用“LAST_NAME”。
似乎我需要解析查询,然后用正确的名称替换字段引用。我发现ODataUriParser似乎可以帮助解决这个问题,但它并不像我希望的那样干净。
有人能提供一些解决这个问题的建议吗?有更好的方法吗?
答案 0 :(得分:5)
WebApi OData新功能模型别名可以解决您的问题。您不必在Edm模型和aDTO之间使用相同的名称。例如,有一个属性名称OrderDto.Total,但在Edm Model中它变为Order.Check
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.ModelAliasingEnabled = true;
EntitySetConfiguration<CustomerDto> customers = builder.EntitySet<CustomerDto>("Customers");
EntitySetConfiguration<OrderDto> orders = builder.EntitySet<OrderDto>("Orders");
orders.EntityType.Name = "Order";
orders.EntityType.Property(p => p.Total).Name = "Check";
return builder.GetEdmModel();
请参考https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/
中的ODataModelAliasingSample