【发布时间】:2014-03-18 15:45:47
【问题描述】:
我正在开发一个 OData 服务,该服务公开了一个使用 Entity Framework 6 创建的模型。这些实体是只读的,并且加载起来非常大。 (几千兆字节)
为了实现这一点,我正在使用 Microsoft.OData.EntityFrameworkProvider,(我目前没有使用 WebAPI)这大部分工作正常,但是我有一个新要求需要公开一个实际上是多个联合的实体为我们的最终用户/客户提供方便的其他实体。
EF 上下文片段
...
public DbSet<Foo> FooRecs { get; set; }
public DbSet<Bar> BarRecs { get; set; }
public IQueryable<FooBarRec> FooBarRecs
{
get
{
return FooRecs.Select(f => new FooBarRec() { Id = f.Id, Description = f.Description })
.Union(
BarRecs.Select(b => new FooBarRec() { Id = b.Id, Description = b.Description })
);
}
}
...
我无法通过 odata 公开此 IQueryable 属性,因为 EntityFrameworkProvider 似乎只公开 DbSets 而不是任何 IQueryable 对象,这是有道理的。
我的问题是,使用 OData 完成此任务的最佳方法是什么?
我想避免将重复数据加载到第三个中间表中,因为数据可能很大,而且加载该数据的时间是每晚完成的。看来 QueryInterceptor 只允许您对已经查询过的数据进行子过滤,因此这似乎不起作用。
我尝试做一些疯狂的事情,比如扩展 DbSet 并制作我自己的 DbViewSet,它在它的构造函数中接受两个集合,但找不到关闭循环的方法。
使用 OData 和 EF6 完成类似于视图的最佳方法是什么?
谢谢!
【问题讨论】:
-
好吧,如果两个集合返回相同的 POCO ...
-
为了清楚起见,从技术上讲,FooBarRec 与 Foo 具有相同的结构,但与 Bar 不同。无论如何,您不能将查询投射到映射实体上:stackoverflow.com/questions/5325797/… 在这种情况下,我决定创建一个未映射的 POCO 来表示联合集,以便我可以对实体集进行子过滤。我的问题是如何在 OData 中表示这一点
-
我知道这没什么用,但是您需要 TSQL 中的联合服务器端和映射的 POCO 来让 OData 为您工作。
-
如果联合由视图执行,EF 仍然可以在 ODataController 指定时应用额外条件。
-
您不能在同一服务中混合使用 Entity Frawmework 数据提供者和其他提供者。阅读WCF, OData, DbContext, and Joins
标签: c# entity-framework odata entity-framework-6