处理 API 和数据库中的可选查询参数

时间:2020-12-19 12:08:46

标签: c# sql asp.net-core

我正在研究 .Net 核心 API,并且有一个分页端点,可以采用可选的查询参数。例如,端点列出项目,您还可以指定过滤包含或等于特定值的字段。

https://endpoint/items?pageparams=pageData&field1Contains=value&field1Equals=value&field2Contains=value&field2Equals=value

[HttpGet]
[Authorize(AuthenticationSchemes = AuthSchemes)]
[Route("items")]
public async Task<IActionResult> GetPagedItems(
      [FromQuery] PageParameters pageParameters, 
      [FromQuery] OptionalSearchParams searchParameters)
{
      // logic
}

目前我将包含视为高于等于的高阶,因此如果您为同一字段同时传递 'equals' 和 'contains',将应用 'contains' 而忽略 'equals'。

API 还动态构建查询和 where 子句,出于明显的安全原因,我真的不想这样做。

 var searchClauses = new List<string>();

 if (!string.IsNullOrEmpty(searchParameters.Field1Contains))
 {
      searchClauses.Add($" ([Field1] LIKE '%{searchParameters.Field1Contains}%')");
 }
 else if (!string.IsNullOrEmpty(searchParameters.Field1Equals))
 {
      searchClauses.Add($" ([Field1] = '{searchParameters.Field1Equals}') ");
 }
 // logic to read other optional params and add where clauses to list

 var query = @$"SELECT TOP {pageParameters.PageSize} 
                -- statement removed for brevity --
                FROM [SomeTable]
                ORDER BY [Field]
                OFFSET {((pageParameters.PageNumber - 1) * pageParameters.PageSize)} ROW) 
                    BASE 
                WHERE {string.Join(" AND ", searchClauses)}

我遇到的问题是我不知道如何将这些值作为参数/存储过程传递给数据库,因为它们不会总是被使用,并且有基于优先级应用的逻辑。不完全正确...我确实设法构建了一个 SQL 查询,但它很庞大,并且在 where 子句中有太多嵌套的 case/select 语句,这将是维护/性能影响的噩梦。

是否有更好的方法来处理可选字段过滤器,同时以参数化方式进行分页?我真的不想从数据库中获取每个项目然后过滤,因为有可能返回数千个项目。

1 个答案:

答案 0 :(得分:0)

Vladimir 指定的阅读为我指明了最佳方向,特别是由过程本身生成然后执行的动态 sql。见http://www.sommarskog.se/dyn-search.html#paramquery

相关问题