您可以将 SQL 查询字符串传递给 Web API 控制器吗?

问题描述 投票:0回答:2

我正在尝试构建一个表单,根据用户的搜索首选项构建 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 错误。

这是正确的做法吗? 任何建议将不胜感激!

c# .net winforms
2个回答
1
投票

唯一应该在层之间传递 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();

0
投票

将所需信息作为查询字符串变量传递。 然后,对它们进行完整性检查。然后使用存储过程并将它们作为参数对象传递。

更好的是使用像实体框架这样的 ORM。

© www.soinside.com 2019 - 2024. All rights reserved.