如何将针对 DTO 的 OData 查询映射到 EF 实体?

2024-01-11

我在 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,例如 -Could not find a property named 'LastName' on type 'MyDataService.Models.RECORD。这是因为 EF 属性具有不同的命名约定。在这种情况下,应该使用“LAST_NAME”。

看来我需要解析查询,然后用正确的名称替换字段引用。我发现 ODataUriParser 似乎可以帮助解决此问题,但它并不像我希望的那么干净。

任何人都可以为我提供一些解决此问题的指示吗?有更好的方法吗?


WebApi OData 新功能模型别名可能会解决您的问题。 Edm 模型和 aDTO 不必具有相同的名称。例如,有一个属性名称 OrderDto.Total,但在 Edm 模型中它变为 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();

请参考 ODataModelAliasingSamplehttps://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将针对 DTO 的 OData 查询映射到 EF 实体? 的相关文章

随机推荐