使用WebApi和映射模型实现OData

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

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

我在另一篇文章中看到其他人没有注意到这一点,但是,它只是该post的一小部分,似乎没有帮助。

还有其他人处理过这件事吗? 我真的不想暴露EF类。 哦,我先使用DB。

提前致谢…

这里有一些代码可以certificate您的要求。

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

 public PageResult Get(ODataQueryOptions queryOptions) { var data2 = DatabaseData(); //Create a set of ODataQueryOptions for the internal class ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); modelBuilder.EntitySet("DatabasePoco"); var context = new ODataQueryContext( modelBuilder.GetEdmModel(), typeof(DatabasePoco)); var newOptions = new ODataQueryOptions(context, Request); var t = new ODataValidationSettings() { MaxTop = 25 }; var s = new ODataQuerySettings() { PageSize = 25 }; newOptions.Validate(t); IEnumerable results = (IEnumerable)newOptions.ApplyTo(data2, s); int skip = newOptions.Skip == null ? 0 : newOptions.Skip.Value; int take = newOptions.Top == null ? 25 : newOptions.Top.Value; List internalResults = results.Skip(skip).Take(take).ToList(); // map from DatabasePoco to WebPoco here: List webResults; PageResult page = new PageResult( webResults, Request.GetNextPageLink(), Request.GetInlineCount()); return page; } 

这是using语句

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

考试class

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

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