关闭。这个问题是基于意见的。它目前不接受答案。
**想改进这个问题吗?**更新这个问题,这样就可以通过编辑这篇文章用事实和引文来回答。
10个月前关门了。
改进这个问题
我有一个api,它从请求中获取它的模型。它将其传输到一个小的存储过程。sp通过使用模型的一些参数来选择一些记录。它以对象列表的形式返回匹配的记录。最后,控制器返回响应。
简化示例:
public IHttpActionResult Get([FromBody]TestModel testModel)
{
var responseList = _testService.GetResponse(testModel);
return Ok(responseList );
}
api一次返回的记录不应超过500条。如果我们有超过这个数量,api应该返回一个错误:“您的请求将返回超过500条记录”。
为检索到的记录数添加验证的最佳解决方案是什么?
两个选择具有相同的条件和联接,但其中一个只返回 count(*)
?
或者将所有数据返回到应用程序,然后在那里进行计数?
或者别的什么?
3条答案
按热度按时间nwlls2ji1#
通常,当您在执行restapi时,有太多的方法可以做到这一点。
进近#1:
一种是在sql级别,您需要传递给sql逻辑分页参数,如
因此,您可以选择并跳过所需的元素数。那有什么好处?您可以在sql查询中添加一些执行计划,查看缺少哪些索引,您可以在sql端优化查询。DBA通常负责大型组织中的这些方法。
进近#2
您仍然可以从后端编写查询,至少这个查询很简单,它将在sql server端执行,下面是一个扩展方法,您可以使用它来执行。
进近#3:
将数据放入内存(在这种情况下,将在服务器端执行,而不是在sql server中)并从此处开始分页。唯一需要做的就是调用tolist(),它将具体化查询并将其放入内存,在内存中您可以使用相同的方法2。
进近#4:
此示例将适用于.NETCore,但请确保有一个版本的包可以对.netframework执行相同的操作。使用odata nugget包
添加
EnableQueryAttribute
然后传球ODataQueryOptions<TestModel> options
,odata使用了一些扩展方法IQueryble
```[EnableQuery]
public IHttpActionResult Get(ODataQueryOptions options)
{
//this should return an IQueryble
var responseList = _testService.GetResponse(testModel);
var ret= options.ApplyToWithDefaultTop(responseList, ignoreQueryOptions);
return Ok(ret);
}
public static IQueryable ApplyToWithDefaultTop(this ODataQueryOptions options,
IQueryable query, AllowedQueryOptions ignoreQueryOptions)
{
if (options.Top == null)
{
//this is the default
query = query.Take(500);
}
https://localhost:44335/api/weather_forecast?$top=40&$skip=2
app.UseMvc(routerBuilder =>
{
routerBuilder.EnableDependencyInjection();
//adding MaxTop from appsettings with a value of 100
//routerBuilder.Select().OrderBy().Filter().Count().MaxTop(Configuration.GetValue("Odata:MaxTop"));
routerBuilder.Expand().Select().Count().OrderBy().Filter().MaxTop(Configuration.GetValue("500"));
});
v2g6jxz62#
你可以通过考试
Output
设置为count
大于500并选择记录,否则不要在sp中执行任何操作。在c代码中,只需首先检查输出值,然后进行相应的处理。oiopk7p53#
正如@viveknuna指出的,您可以使用out参数来指示检索到的行计数。
我想对他的建议补充几点:
1) 建议仅在超过预定义阈值时设置该参数。我建议每次都设置它,并在应用程序代码中检查它。它给你更多的灵活性。
2) 您不需要使用两个选择。
@@ROWCOUNT
或者ROWCOUNT_BIG()
我建议读一读这篇关于这个主题的优秀文章。