【发布时间】:2013-04-01 09:41:54
【问题描述】:
我在 VS 2012 中创建了一个 WebApi 项目,使用 NHibernate 作为我的 ORM,我打算在其上启用 Odata 支持。因此,我创建了一个带有单个 Get 方法的测试控制器,该方法从我的数据库中的表中返回实体列表。
一切正常,我可以使用 OData 过滤和排序我的结果等。问题是我找不到限制从数据库返回到控制器的数据量的方法,而这个表有数百万条记录。
使用Queryable 属性的PageSize 属性似乎只限制了返回给客户端的数据量,但没有限制从数据库返回的数据量。
我尝试在返回之前在 get 方法中的 IQueryable 上应用 Take(n),它会限制从数据库返回的结果,但它会破坏 OData 过滤,因为如果您尝试查询不在前 n 个结果中的实体,它只返回一个空集合。
我知道您可以使用 OData 上的 $Top 参数来完成此操作,但我不想依赖提供它的客户/消费者,以确保我不会不必要地带来数千甚至数百万条记录我不会用的。
我还尝试手动检查客户端是否在查询字符串上提供了 Top 参数,将 OData 转换应用于我的 Queryable,然后在转换后的查询上应用 Take(n) 方法。这种方法使我能够通过 OData 过滤任何实体,但它会破坏分页,因为如果我使用 $Skip=n 参数,它会再次返回一个空集合。
那么,有什么方法可以在不破坏 OData 支持的情况下可靠地限制从数据库中获取的结果?
【问题讨论】:
-
您使用什么作为 OData 和 NHibernate 之间的桥梁?您是手动将 OData 转换为 NHibernate IQueryable 还是使用库?此外,在过去,我看到人们自动将 TOP 1000 强加于通过 API 返回的所有结果,并发送一些信息表明他们只收到了部分请求的数据,并且通常提供调用者可以使用的预先创建的 URL使用它将返回接下来的 1000 个结果。调用者将继续使用提供的 URL,直到他们收到所有数据。
-
我没有使用 OData 直接创建查询,而是作为我的客户从现有方法过滤返回结果的便捷工具。例如,我有一个 GetAllProducts() 方法,它使用 Linq to NHibernate 执行查询,然后我返回该 IQueryable。您描述的行为是在 Queryable 属性上使用 PageSize 属性时的默认行为,但正如我在帖子中提到的那样,这只会限制客户端接收的内容,而不是从数据库获取到我的服务方法的结果。
标签: asp.net-mvc linq nhibernate asp.net-web-api odata