2011-02-04 6 views
0

私はこのクエリをLINQで翻訳したいと思っています...純粋なSQLで作成したものの、動的に作成したLINQクエリ(ユーザー入力に基づいて検索クエリを作成する)では非常に簡単です。全く新しい話。LINQでこのクエリを翻訳していますか?

SELECT * FROM MyTable 
WHERE 1=1 
    AND Column2 IN (1,2,3) 
    AND (Column1 LIKE '%a%' OR Column1 LIKE '%b%') 

これを構築しようとする私たちは、このようにそれを試してみました:

if(myOjb.Column2Collection != null) 
    query = query.where(f => f.Column2.Contains(myOjb.Column2Collection)); 

if(myObj.Column1Collection != null) 
{ 
    // tough part here ? 
    //query = query.Where(); ... 
} 

だから何が正常にこれに最善のaproachだろうか?私はここでそれを実装する方法を理解することはできませんカントー、SqlMethod.Likeを認識してい

注...

+0

WHERE 1 = 1の目的は何ですか?それは単に「真実」を意味するものではなく、違いを生じさせませんか? – Marcus

+6

@ G_M - これは通常、動的SQLを構築するときに行われ、既存のwhere句のチェックを続ける必要はありません。 – Oded

+0

ORを動的に処理する方法はあなたの質問ですか? – JohnOpincar

答えて

0

すると、このようなものを試してみてください:

var colums2 = { 1, 2, 3 }; 
var result = (from o in myOjb 
       where columns2.Any(co2 => co2 == o.Column2) 
       && Column1.Contains(column2valueA) 
       || Column1.Contains(column2valueB) 
       select o); 

希望は

を助けることができます
+0

彼が持っている問題は 'column2value'はリストです検索するもののうち... – cjk

+0

ああ...すみません。 –

+0

'ToLower()'を使わず、代わりに 'StringComparison'を使用してください – abatishchev

0
var sc = StringComparison.OrdinalIgnoreCase; 
var col2Values = new int[] { 1, 2, 3 };  

var query = from item in myObj 
      where col2Values.Contains(item.Column2) 
      && (item.Column1.IndexOf("a", sc) >= 0 
       || item.Column1.IndexOf("b", sc) >= 0) 
      select item; 

これはまだテストされていませんが、うまく構築されています。オリジナルバージョンは、上記に失敗した場合:

var col2Values = new int[] { 1, 2, 3 }; 

var query = from item in myObj 
      let col1 = item.Column1.ToLower() 
      where col2Values.Contains(item.Column2) 
      && (col1.Contains("a") || col1.Contains("b")) 
      select item; 

私は実際にそれがToLower()のため少し遅い場合でも、第二のバージョンを好みます。私の目には、読むのが簡単です。 YMMV。

+0

代わりに 'ToLower()'を使わず、代わりに 'StringComparison'を使います – abatishchev

+0

@abatishchev:' StringComparison'は私が覚えようとしていたものでした。私は編集します。 –

+0

動的に作成されたクエリでは動作しませんが、%演算子では動作しません。SqlMethods.Like()はそれを処理する方法ですが、ここで動作させる方法はわかりません。 – Erick

0
from o in myObj 
where 
new[] { 1, 2, 3 }.Contains(o.Column2) && 
new[] { "a", "b" }.Any(s => o.Column1.IndexOf(s, StringComparison.Ordinal) != -1) 
select o; 

たり、検索のパフォーマンスを心配している場合new Hashset<T>を使用しています。 ArrayはO(n)のみを持ちます。


Ordinalユニコード比較バイトバイトあたりのカルチャ固有の問題もなく、最も速いことを意味します。

OrdinalIgnoreCaseは同じことを意味しますが

+0

ここでの問題は、SqlMethod.Likeのような%演算子では機能しませんし、括弧のリストでも動作しません。((where1またはwhere2)) – Erick

+0

@Erick:少し編集しました正確にあなたのクエリに対応します。 – abatishchev

+0

これはコンパイルされません。 'string.Contains'はパラメータとして' StringComparer.Ordinal'を取るこ​​とができません。そして、4行目にはaがありません。 –

1

「Like ... or Like ..」を取得するには、独自の拡張を作成して式ツリーを作成する必要があると思います。 、私はあなたがこれを書くと思います。そこからLinq to Sql any keyword search query

string[] terms = new string[] {"a", "b"} 
query = query.LikeAny(table => table.Column1, terms) 

ところで、あなたはまた、上のコードを変更することができ、私はしばらく前にこれをやってみたかったとStackOverflowの上ここでは別の記事を見つけてしまいました行うにはリンク先のページというよりOR

var body = conditions.Aggregate((acc, c) => Expression.And(acc, c)); 

var body = conditions.Aggregate((acc, c) => Expression.Or(acc, c)); 

を変化させることにより、 1

これはLikeAllと呼んでいた当時のものでした。

関連する問題