Как мне сопоставить запрос OData с DTO к объекту EF?

У меня есть ODataController в приложении Asp.Net Web Api, которое позволяет запросы OData. Я разрешаю только чтение, а не обновления. Вместо того, чтобы напрямую представлять модель данных, я создал набор DTO. Имена свойств в DTO не обязательно совпадают со свойствами в модели EF. Это вызывает проблему, когда я пытаюсь использовать запрос OData к модели EF. Я просмотрел другие посты в Stackru по этой теме, но ни одна из них, похоже, не решила эту проблему.

Вот что у меня сейчас есть:

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, который, кажется, мог бы помочь с этим, но он не так чист, как я надеялся.

Кто-нибудь может дать мне несколько советов по решению этой проблемы? Есть ли лучший подход?

1 ответ

Решение

Новая функция "Псевдоним модели WebApi OData" может решить вашу проблему. Вам не обязательно иметь одинаковые имена между Edm Model и 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();

Пожалуйста, обратитесь к ODataModelAliasingSample в https://aspnet.codeplex.com/SourceControl/latest

Другие вопросы по тегам