我正在尝试构建一个表单,根据用户的搜索首选项构建 SQL 查询字符串,然后将查询传递到从数据库获取数据的 API 控制器。
[Route("api/SelectionHelper/RiskGridView/{query}")]
[HttpGet]
public HttpResponseMessage RiskGridView(string query)
{
try
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Actor"].ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Table WHERE key ='" + Constants.GlobalId + "'", con))
{
DataTable dt = new DataTable();
SqlDataAdapter adp = new SqlDataAdapter(cmd);
adp.Fill(dt);
if (dt.Rows.Count == 0)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "No active session found");
}
else
{
List<RiskSearch> list = new List<RiskSearch>();
cmd.CommandText = query;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
list.Add(new RiskSearch()
{
QuoteRef = Convert.ToInt32(reader["ref"]),
PolicyRef = reader["reference"].ToString(),
Insured = reader["sap_ins_name"].ToString(),
QuoteStatus = reader["status"].ToString(),
Order = Convert.ToInt32(reader["recd"]),
InceptionDate = Convert.ToDateTime(reader["inception"]).ToShortDateString(),
PolicyType = reader["type"].ToString(),
Broker = reader["name"].ToString(),
QuoteStatusDate = Convert.ToDateTime(reader["date"]).ToShortDateString(),
RiskStatus = reader["status"].ToString()
});
}
return Request.CreateResponse(HttpStatusCode.OK, list);
}
}
}
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
}
如何构建查询
if (txt_ref.Text != "")
{
SearchString += "[table].[field]" +
CreatedFunctions.fct_SQL_WhereSearchStringText(txt_ref.Text);
}
if (txt_reference.Text != "")
{
SearchString += "[Table].[Field]" +
CreatedFunctions.fct_SQL_WhereSearchStringText(txt_reference.Text);
}
if (txtPolicyGroup.Text != "")
{
SearchString += "[Table].[Field]" +
CreatedFunctions.fct_SQL_WhereSearchStringText(txt_Group_ref.Text);
}
if (txt__name.Text != "")
我尝试将查询作为字符串变量传递到 url 中,但它会抛出 404 或 400 错误。
这是正确的做法吗? 任何建议将不胜感激!
唯一应该在层之间传递 SQL 的系统是本质上是 SQL 工具(例如,SEDE)。
在所有其他情况下,您几乎肯定应该在表示可用搜索选项的层之间传递一些 DTO,例如
public HttpResponseMessage RiskGridView(string reference = null, string policyGroup = null, ... )
或通过 json:
class SearchRequest {
public string Reference {get;set;}
public string PolicyGroup {get;set;}
// ...
}
public HttpResponseMessage RiskGridView(SearchRequest query)
现在
RiskGridView
方法将使用 parameters(不是串联)构建所需的 SQL。调用系统不需要知道表格布局。
我还强烈建议使用“Dapper”之类的工具,以便在构建后实际执行它:
...
if(opt.Reference != null) sql.Append(" and x.Reference=@Reference");
if(opt.PolicyGroup != null) sql.Append(" and x.PolicyGroup=@PolicyGroup");
//...
var results = connection.Query<RiskSearch>(sql.ToString(), opt); // handles params/reader
或者使用像 LINQ 这样的工具:
IQueryable<RiskSearch> rows = ctx.RiskSearch;
if(opt.Reference != null) rows = rows.Where(x => x.Reference == opt.Reference);
if(opt.PolicyGroup != null) rows.Where(x => x.PolicyGroup == opt.PolicyGroup);
// ...
var results = rows.Take(count).ToList();
将所需信息作为查询字符串变量传递。 然后,对它们进行完整性检查。然后使用存储过程并将它们作为参数对象传递。
更好的是使用像实体框架这样的 ORM。