2014-04-09 11 views
7

Ho un ODataController in un'applicazione Asp.Net Web Api che consente le query OData. Permetto solo letture, non aggiornamenti. Invece di esporre direttamente il modello di dati, ho creato una serie di DTO. I nomi delle proprietà sui DTO non corrispondono necessariamente alle proprietà sul modello EF. Ciò causa un problema quando provo a utilizzare la query OData sul modello EF. Ho esaminato altri post su StackOverflow attorno a questo argomento, ma nessuno di essi sembrava risolvere questo problema.Come si associa una query OData a un DTO a un'entità EF?

Ecco quello che ho in questo momento:

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); 
} 

Questo funziona fino a quando non fare riferimento ai campi specifici in una selezione o filtro. Non appena faccio riferimento a un campo nella mia query OData ottengo un ODataException come - Could not find a property named 'LastName' on type 'MyDataService.Models.RECORD. Questo perché le proprietà EF hanno una convenzione di denominazione diversa. In questo caso dovrebbe utilizzare "LAST_NAME".

Sembra che ho bisogno di analizzare la query e quindi sostituire i riferimenti di campo con i nomi corretti. Ho trovato ODataUriParser che sembra possa aiutare in questo, ma non è così pulito come speravo.

Qualcuno può fornirmi alcuni suggerimenti per risolvere questo problema? C'è un approccio migliore?

risposta

5

La nuova funzionalità WebApi OData Model Aliasing può risolvere il problema. Non è necessario avere lo stesso nome tra un modello Edm e un aTO. per esempio, v'è un nome di proprietà OrderDto.Total, ma in Edm Modello diventa 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(); 

Si prega di fare riferimento al ODataModelAliasingSample in https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/

+0

Grazie. Questo è stato estremamente utile. Al momento è disponibile solo in pre-release, ma sembra promettente. Inoltre, è possibile utilizzare gli attributi DataContract e DataMember sul modello per definire l'alias. – BenR

+2

Inoltre, penso che la proprietà ModelAliasingEnabled sia stata deprecata con la versione più recente ma l'aliasing funziona ancora. – BenR

+0

Questo alias può essere utilizzato anche quando si implementano query OData all'interno di un ApiController? –

Problemi correlati