我正在尝试在WebApi中实现OData。我正在使用存储库模式和EF5(在后端),这仍然与我找到的所有示例一致。这是事情变得不稳定的地方。我试图隐藏EF生成的类隐藏在控制器中使用AutoMapper映射的模型后面。我看到的例子似乎返回了来自回购的任何内容
我不想在控制器中但在存储库中应用OData参数(已映射的结果)以保留延迟执行的值。我可以将ODataCriteria传递到存储库中,但是当我尝试Appy时,我收到一个错误,因为看起来选项/结果被输入到IQueryable<型号>来自表示层而不是IQueryable< EF_Class>。
我在另一篇文章中看到其他人没有注意到这一点,但是,这只是该帖子的一小部分,它似乎没有帮助。
还有其他人处理过此事吗?我真的不想公开EF课程。哦,我先使用DB。
提前致谢...
答案 0 :(得分:0)
如果您返回的Queryable是通过dbContext.dbSet.Select(x => new Model {Id = x.Id})机制而不是AutoMapper。然后,可以由EF LINQ提供程序自动翻译和评估在Queryable上应用条件。否则,您将不得不编写一个自定义LINQ提供程序,该提供程序将表达式从基于Model属性的表达式更改为EF_Class属性之外的表达式。
答案 1 :(得分: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();
}