Как мне сопоставить запрос 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