2017-03-18 3 views
1

パラメータ化されたSQLクエリが記述されていないアプリケーションに含まれています。INキーワードでパラメータ化するクエリC#

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(); 
     } 
    } 

私はこのクエリを実行するには、データを取得していない:以下は、私はこのようなパラメータ化クエリを使用してコードをリファクタリングしていたコードブロック

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(); 
    } 

です。デバッグで私のクエリがこのように形成されていることがわかりました

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

私はデータを「エラー」、「警告」と表示しています。私はこの

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

のようなクエリを実行するSQL Serverでは は私がmystateの周りに「」削除する必要がありますか?私はまだ二重引用符を見ることができます。私は、「削除トリムの方法を使用して、バック文字列にそれを割り当てるしようとしたが、それはうまくいきませんでした。同じ

のための任意の文字列ビルダを使用せずに、より良い私のクエリをパラメータ化するにはどうすればよい

myStates = myStates.trim('"'); 

答えて

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(); 
    } 
} 
+0

私が言ったとき、私は "エラー"、 "警告"のような結果を得ました。エラー単語の前に一重引用符が付きません – pankaj

+0

私は、一重引用符の先頭と末尾を含めるように答えを修正しました。 –

+0

私はあなたが言ったように..まだ結果が得られません – pankaj

0

は、私はあなたがパラメータを渡す方法変更すべきだと思います。参考のため

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

here見つけることができるこの方法、の署名を見てください

1

代替案:Dapperの...

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 ifそれはあなたのサーバーでサポートされています。

+0

私はレガシーアプリに入っています。新しいものを自由に使うことはできません。私の問題に対する解決策は何ですか? – pankaj

+0

@ sameer私は、「新しいルールを使用しないでください」という人を叩くことを提案しています。これは恐ろしい問題を解決するものと思われます(注意:これは誇張です。 –

関連する問題