我有一个ASP.NET WebAPI项目。我最近为我的所有数据表创建了EntityFramework实体。但我不想暴露我的数据层和架构给我的用户。如何将我的实体映射到ViewModel(automapper?)和提供IQueryable返回类型,以便我的API支持OData?
OData支持查询组合和类似SQL的参数。我想我需要为查询组合部分提供某种双向翻译?这是否意味着自定义LINQ提供程序?我希望它比那更容易。
或者我应该放弃IQueryable / OData?
答案 0 :(得分:10)
我在这里找到答案:Web API Queryable - how to apply AutoMapper?
您可以使用[Queryable]
类型的参数来对任何类型或LINQ查询应用OData操作,而不是使用ODataQueryOptions<T>
。这是一个很好的例子,甚至不需要使用AutoMapper:
public virtual IQueryable<PersonDto> Get(ODataQueryOptions<Person> odataQuery){
odataQuery.Validate(new ODataValidationSettings(){
AllowedFunctions = AllowedFunctions.AllMathFunctions
});
var people = odataQuery.ApplyTo(uow.Person().GetAll());
return ConvertToDtos(people);
}
这里是the Microsoft page解释这种用法的具体细节。 (大约一半)
答案 1 :(得分:6)
我能够使用ViewModel类成功测试它。
public class InvoiceViewModel
{
public int InvoiceID { get; set; }
public string InvoiceNumber { get; set; }
}
在获取中,从您的实体中选择您的视图模型:
public override IQueryable<InvoiceViewModel> Get()
{
var ctx = new CreditPointEntities();
return ctx.Invoices.Select(i => new InvoiceViewModel
{
InvoiceID = i.InvoiceID,
InvoiceNumber = i.InvoiceNumber
}).AsQueryable();
}
确保在webapiconfig.cs的modelbuilder行中使用viewmodel
modelBuilder.EntitySet<InvoiceViewModel>("Invoice");
有了这个,你可以使用像
这样的网址 http://website/odata/Invoice?$filter=InvoiceID eq 1
我通过sql profiler确认过滤器正在传递给SQL。
答案 2 :(得分:1)
如果您使用的是Automapper,则可以在其中使用投影。例如:
public class ProductsController : EntitySetController<Product, int>
{
private DbProductsContext _db = new DbProductsContext();
public override IQueryable<ProductDto> Get()
{
return _db.Products.Project().To<ProductDto>();
}
...