12

我有一个 ASP.NET WebAPI 项目。我最近为我的所有数据表创建了 EntityFramework 实体。但我不想将我的数据层和架构暴露给我的用户。如何将我的实体映射到 ViewModel(自动映射器?)提供 IQueryable 返回类型,以便我的 API 支持 OData?

OData 支持查询组合和类似 SQL 的参数。我想我需要为查询组合部分提供某种双向翻译?这是否意味着自定义 LINQ 提供程序?我希望它比那更容易。

还是我应该放弃 IQueryable/OData?

4

3 回答 3

12

我在这里找到了答案:Web API Queryable - 如何应用 AutoMapper?

[Queryable]您可以使用类型参数代替使用,ODataQueryOptions<T>以针对您希望的任何类型或 LINQ 查询应用 OData 操作。这是一个很好的例子,它甚至不需要使用 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);
}

这是解释此用法细节的 Microsoft 页面。(大约下降一半)

于 2013-03-05T17:53:13.830 回答
6

我能够使用 ViewModel 类成功地对此进行测试。

public class InvoiceViewModel
{
    public int InvoiceID { get; set; }
    public string InvoiceNumber { get; set; }
}

在 Get 中,从您的实体中选择到您的视图模型中:

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.EntitySet<InvoiceViewModel>("Invoice");

有了这个,你可以使用一个像

http://website/odata/Invoice?$filter=InvoiceID eq 1

我通过 sql profiler 确认过滤器正在传递给 SQL。

于 2013-03-01T09:29:00.427 回答
1

如果您使用的是 Automapper,则可以在其中使用投影。例子:

    public class ProductsController : EntitySetController<Product, int>
    {
         private DbProductsContext _db = new DbProductsContext();

         public override IQueryable<ProductDto> Get()
         {
            return _db.Products.Project().To<ProductDto>();
         }
    ...
于 2013-02-21T17:34:50.057 回答