在MVC应用程序中使用动态参数管理查询

本文关键字:动态 参数 管理 查询 MVC 应用程序 | 更新日期: 2023-09-27 18:25:19

我正在开发一个web应用程序,在该应用程序中,用户可以将查询、连接字符串和查询参数保存为应用程序数据库中的一行表。稍后,应用程序将提供一个下拉列表,其中包含数据库中保存的所有查询,用户可以选择要运行的查询。

我的问题是,我将使用以下格式进行查询:

select * from table where field = {0} and field = {1}

我将在数据库中有一列,其中包含每个参数的确切数量和类型,大致如下:"D|N|S",相应地指示日期、数字或字符串。

在应用程序中,我目前有一个控制器操作,用于检索一个字符串中的查询和另一个字符串的参数,因此在控制器中,我知道查询有多少个参数和哪种类型的参数,但我无法提供如何在视图中创建html控件以供用户输入这些参数的值的好解决方案。因为在控制器从数据库中获取查询之前,我不知道查询有多少参数,所以我不确定如何继续。

提前谢谢。

在MVC应用程序中使用动态参数管理查询

这将帮助您开始:

它将在表单中添加动态输入元素。表单指向一个控制器后操作,该控制器后操作将接收SqlParams的列表,在那里你可以做任何你想做的事情。

当然,你必须添加你的验证,并根据你的需求进行调整,它看起来像这样:

服务器:

public class HomeController : Controller
    {
        public class SqlParams 
        {
            public string Name { get; set; }
            public string Value { get; set; }
            public string ParamType { get; set; }
        }
        public ActionResult SQL() 
        {
            return View();
        }
        [HttpPost]
        public ActionResult SQL(List<SqlParams> sqlParams)
        {
            foreach (var item in sqlParams)
            {
                //Do whatever 
                string query = string.Format("{0} = {1}, {2}",item.Name,item.Value, item.ParamType);                
            }
            return View();
        }
}

视图:

<button type="button" onclick="Add();">Click to add param</button>
<form action="@Url.Action("SQL")" method="post">

    <div id="controls">
    </div>
    <button type="submit">Save query</button>
</form>
@section scripts {
    <script>
        var counter = 0;
        function Add() {
            var html = "<label>Parameter Name: </label> <input name='sqlParams[" + counter + "].Name'/> <br/>" +
                       "<label>Parameter Value: </label> <input name='sqlParams[" + counter + "].Value'/> <br/>" +
                       "<label>Parameter Type: </label> <input name='sqlParams[" + counter + "].Type'/> <br/>";
            counter++;
            $("#controls").append(html);
        }
    </script>
    }

我会有一个用于查询和参数的类,其中查询有一个参数集合。

public class SomeQueryClassName
{
    public int QueryId { get; set; }
    public string ConnectionString { get; set; }
    public string CommandText { get; set; }
    public List<SomeParameterClassName> Parameters { get; set; }
    public SomeQueryClassName()
    {
        ....
    }
}
public class SomeParameterClassName
{
    public string Name { get; set; }
    public string Description { get; set; }
    public string DataType { get; set; }
    public object Value { get; set; }
    public SomeParameterClassName()
    {
        ....
    }
}

然后在控制器中获取查询并返回参数列表作为模型。

public ActionResult GetQuery(int queryId)
{
    var query = 
    return View(SomeFunctionToGetTheQuery(queryId).Select(x => x.Parameters).ToList());
}
public ActionResult RunQuery(List<SomeParameterClassName> parameters)
{
    //some server side validation
    //GetQueryResults will add the parameters and execute the query
    return View(GetQueryResults(parameters);
}

然后在视图

using (Html.BeginForm())
{
    for (int i = 0; i < Model.Count; i++))
    {
        var parameter = Model   [i];     
        <div class="formGroup">
            <div class="labelDivClass">
                <label class="labelClass>@parameter.Description</label>
            </div>
            <div class="inputDivClass">
                <input type="text" name="[i].Value" class="someClassUsedForClientSideValidationBasedOnParameterDataType" />
                <input type="hidden" name="[i].Name" value="@parameter.Name"/>
                <input type="hidden" name="[I].DataType" value="@parameter.DataType"/>
            </div>
        </div>
    }
}

在保存/执行查询时,请确保使用参数化查询并添加参数,而不是将值连接到查询中。

using (var connection = new SqlConnection("some connection string"))
{
    connection.Open();
    string cmd = "select * from testable where testcolumn = @testvalue";
    using (var command = new SqlCommand(cmd,connection))
    {
        command.Parameters.AddWithValue("testvalue",somevalue);
        //execute query and return data in a datatable or yield return objects
    }
    connection.Close();
}