我在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查询中引用一个字段时,我得到一个类似于ODataException – 无法在类型’MyDataService.Models.RECORD上找到名为’LastName’的属性.这是因为EF属性具有不同的命名约定.在这种情况下,它应该使用“LAST_NAME”.
看起来我需要解析查询,然后用正确的名称替换字段引用.我发现ODataUriParser似乎可以帮助解决这个问题,但它并不像我希望的那样干净.
解决方法
WebApi OData新功能模型别名可以解决您的问题.您不必在Edm Model和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