使用IN关键字c#参数化查询

时间:2017-03-18 18:11:50

标签: c# orm

我在不编写参数化Sql查询的应用程序中。下面是代码块

  public List<MyClass> GetData(int Id, IEnumerable<string> state)
    {
        using (var dataContext = new DataContext(_connectionString)) 
            {
            var query = new StringBuilder("SELECT * FROM table");
            query.Append(" Id = ");
            query.Append(Id);
            query.Append(" AND state IN ('");
            query.Append(string.Join("','", state));
            query.Append("')");

            return dataContext.ExecuteQuery<MyClass>(query.ToString()).ToList();
     }

我正在使用参数化查询重构代码,如下所示:

    public List<MyClass> GetData(int Id, IEnumerable<string> state)
    {
      using (var dataContext = new DataContext(_connectionString)) 
        {
            var statestring = new StringBuilder("'");
            statestring.Append(string.Join("','", state));
            statestring.Append("'");
             string myStates= statestring.ToString();
            string query = "SELECT * FROM table WHERE Id ={0} AND state IN ({1})";
            return dataContext.ExecuteQuery<MyClass>(query, new object[] {Id, myStates}).ToList();
         }
     }

我没有关于运行此查询的数据。在调试时,我发现我的查询正在形成这样的

  SELECT * FROM table WHERE Id ={0} AND state IN ({1}) where in ({1}) 

对于州,我将数据视为&#34;&#39;错误&#39;,&#39;警告&#39;&#34 ;. 在sql server中我运行像这样的查询

   SELECT * FROM table   WHERE Id =34 AND state IN ('error','warning').

我需要删除&#34; &#34;在mystate周围?我试过删除&#34;使用trim方法并将其分配回字符串但它没有工作。我仍然可以看到双引号。

  myStates = myStates.trim('"');

如何在不使用任何字符串构建器的情况下更好地参数化我的查询

3 个答案:

答案 0 :(得分:1)

另类建议:小巧......

int x = ...;
int[] y = ...
var items = connection.Query<MyClass>(
   "SELECT * FROM table WHERE X = @x AND Y in @y", new {x,y}).AsList();

Dapper将为您处理此问题,使用适当的查询0,1或多个项目,包括(可选配置选项)填充参数以避免查询计划饱和(因此当您有大型列表时,您使用相同的47个项目,48个项目和49个项目的查询和查询计划,但可能是50)的不同查询,并且如果您的服务器支持string_split,则使用ArrayList<Integer> al = new ArrayList<>();

答案 1 :(得分:0)

我认为你应该改变传递参数的方式:

return dataContext.ExecuteQuery<MyClass>(query, Id, stateString).ToList();

如需参考,请查看此方法的签名,可以找到here

答案 2 :(得分:0)

要参数化in子句,每个案例都必须是一个单独的参数。所以in子句必须反映这一点。

请参阅此类似问题:How to pass sqlparameter to IN()?

public List<MyClass> GetData(int Id, IEnumerable<string> state)
{
    using (var dataContext = new DataContext(_connectionString))
    {
        var stateParameterNumbers = Enumerable.Range(1, state.Count())
            .Select(i => string.Format("{{{0}}}", i));

        var stateParameterString = string.Join(",", stateParameterNumbers);

        string query = "SELECT * FROM table WHERE Id ={0} AND state IN (" + stateParameterString + ")";
        return dataContext.ExecuteQuery<MyClass>(query, new object[] { Id }.Concat(state).ToArray()).ToList();
    }
}