9

我正在尝试在 WebApi 中实现 OData。我正在使用存储库模式和 EF5(在后端),这仍然与我找到的所有示例一致。这就是事情出问题的地方。我试图将 EF 生成的类隐藏在控制器中使用 AutoMapper 映射的模型后面。我看到的例子似乎返回了回购的任何内容

我不想在控制器中应用 OData 参数(对已映射的结果),而是在存储库中应用,以保留延迟执行的值。我可以将 ODataCriteria 传递到存储库中,但是当我尝试 Appy 时,我收到一个错误,因为似乎选项/结果是从表示层而不是 IQueryable<EF_Class> 键入到 IQueryable<Model> 的。

我在另一个帖子中看到其他人对此有所回避,但是,这是帖子的一小部分,似乎没有帮助。

有没有其他人处理过这个?我真的不想公开 EF 类。哦,我首先使用数据库。

提前致谢...

4

2 回答 2

0

如果您返回的 Queryable 是通过 dbContext.dbSet.Select(x => new Model { Id = x.Id}) 机制而不是 AutoMapper。然后在 Queryable 上应用条件可以由 EF LINQ 提供程序自动转换和评估。否则,您将不得不编写一个自定义 LINQ 提供程序,它将表达式从基于 Model 属性的表达式更改为来自 EF_Class 属性的表达式。

于 2013-05-16T22:01:03.570 回答
0

这是一些演示您的要求的代码。

要获得结果,您需要确保查询已被执行(使用ToList())。最有效的方法是添加分页(奖励)并返回一个PageResult<>对象。

public PageResult<WebPoco> Get(ODataQueryOptions<WebPoco> queryOptions)
{
    var data2 = DatabaseData();

    //Create a set of ODataQueryOptions for the internal class
    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
    modelBuilder.EntitySet<DatabasePoco>("DatabasePoco"); 
    var context = new ODataQueryContext(
         modelBuilder.GetEdmModel(), typeof(DatabasePoco));
    var newOptions = new ODataQueryOptions<DatabasePoco>(context, Request);

    var t = new ODataValidationSettings() { MaxTop = 25 };
    var s = new ODataQuerySettings() { PageSize = 25 };
    newOptions.Validate(t);
    IEnumerable<DatabasePoco> results =
        (IEnumerable<DatabasePoco>)newOptions.ApplyTo(data2, s);

    int skip = newOptions.Skip == null ? 0 : newOptions.Skip.Value;
    int take = newOptions.Top == null ? 25 : newOptions.Top.Value;

    List<DatabasePoco> internalResults = results.Skip(skip).Take(take).ToList();

    // map from DatabasePoco to WebPoco here:
    List<WebPoco> webResults; 

    PageResult<WebPoco> page =
        new PageResult<WebPoco>(
            webResults, Request.GetNextPageLink(), Request.GetInlineCount());

    return page;
}

这是使用语句

using System.Web.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Query;

测试班

public class WebPoco
{
    public int id { get; set; }
    public string name { get; set; }
    public string type { get; set; }
}

public class DatabasePoco
{
    public int id { get; set; }
    public string name { get; set; }
    public string type { get; set; }
}

和一些测试数据

private IQueryable<DatabasePoco> DatabaseData()
{
    return (
        new DatabasePoco[] { 
            new DatabasePoco() { id = 1, name = "one", type = "a" },
            new DatabasePoco() { id = 2, name = "two", type = "b" },
            new DatabasePoco() { id = 3, name = "three", type = "c" },
            new DatabasePoco() { id = 4, name = "four", type = "d" },
            new DatabasePoco() { id = 5, name = "five", type = "e" },
            new DatabasePoco() { id = 6, name = "six", type = "f" },
            new DatabasePoco() { id = 7, name = "seven", type = "g" },
            new DatabasePoco() { id = 8, name = "eight", type = "h" },
            new DatabasePoco() { id = 9, name = "nine", type = "i" }
        })
        .AsQueryable();
}
于 2013-05-17T10:32:28.607 回答