2013-04-09 100 views
7

我已经在VS 2012中创建了一个WebApi项目,使用NHibernate作为我的ORM,并且我打算启用对它的Odata支持。所以我用一个Get方法创建了一个测试控制器,它从我的数据库的一个表中返回一个实体列表。WebApi控制器和ODATA限制服务器端结果w/Nhibernate

一切工作正常,我可以使用OData过滤和命令我的结果等问题是我找不到方法来限制从数据库返回到控制器的数据量,并且此表有数百万条记录。

使用Queryable属性的PageSize属性仅似乎限制了返回给客户端的数据量,但没有限制从数据库返回的数据量。

我试图返回之前申请的get方法内的IQueryable一个Take(n),它限制了结果从DB带回,但它打破了OData的过滤,因为如果你尝试查询这不是一个实体在前n个结果中,它只是返回一个空集合。

我知道你可以使用OData上的$Top参数来完成这个任务,但我不想依赖提供它的客户端/消费者,以确保我不会不必要地带来数千甚至数百万条记录我不打算使用。

我也试着手动检查客户端是否在查询字符串上提供了Top参数,将OData转换应用于我的Queryable,然后在转换后的查询上应用Take(n)方法。这种方法使我能够通过OData过滤任何实体,但是它破坏了分页,因为如果我使用$Skip=n参数,它将再次返回一个空集合。

那么,有没有办法可靠地限制从数据库中获取的结果,同时不会破坏OData支持?

+1

你在OData和NHibernate之间使用什么桥梁?你是否在将OData转换为NHibernate IQueryable或者你在使用库?另外,在过去,我看到人们会自动对通过API返回的所有结果施加TOP 1000,并发送一些信息,表明他们只收到了部分请求的数据,并且通常会提供一个预先创建的URL,供调用者使用使用它将返回下一个1000个结果。调用者将继续使用提供的URL,直到他们收到所有数据。 – 2013-04-09 23:25:59

+0

我没有使用OData直接创建查询,而是作为我的客户端的便捷工具来筛选现有方法的返回结果。所以例如我有一个GetAllProducts()方法,它执行使用Linq到NHibernate的查询,并且我返回IQueryable。你描述的行为是在Queryable atribute上使用PageSize属性时的默认行为,但正如我在我的帖子中提到的,这只会限制客户端所收到的内容,而不会影响从数据库中获取到我的服务方法的结果。 – andyroschy 2013-04-10 16:32:35

回答

2

我们最近也发现了这一点。当启用服务器驱动分页时,我们不应用Take(pageSize),因为我们必须确定是否应生成下一页链接。我们只枚举pageSize实体的结果集并检查是否有更多的实体。我们认为大多数提供者通常会带来一部分结果,因为IQueryable通常是一个懒惰的实现。结果不是这样。此外,如果数据库只知道pageSize需要的结果数量,则可以优化该查询。

This是为它打开的问题。好消息是优素福已经修复它:)。这是修复它的commit。所以,如果你抓住夜间建设,你应该是好的。

+0

昨天我看到了这个问题,但是如果你点击修正链接,页面就会丢失,这给我一个不好的预感。我会尽力得到最新的构建并测试这个来看看这个。 – andyroschy 2013-04-10 16:27:16

+1

看起来像codeplex不再理解部分sha1。无论如何,这个链接应该工作https://aspnetwebstack.codeplex.com/SourceControl/changeset/8517d73f5f60ffb3e1c8a590af4695c7bda37709 – 2013-04-10 18:29:10