2011-08-14 23 views
0

ユーザーが文を入力したとし、入力された文の中の単語からなる語を検索する必要があるとします。これらは私が彼らがその事件を解決できると思ったコードです。データベース内で文字列内の単語を検索する

var result = from x in dataBase.tableName 
      select x; 

string[] words = enteredString.Split(); 

foreach(string word in words) 
      { 
       result = result.Where(x => x.subject.Contains(word)); 
      } 

それは文の最後の言葉を持つ唯一の検索結果を示しているが、私は結果が単語がどこのラインで使用されるたびに絞り込まれなければならないと思いました。

+0

あなたが与えてくれた何* *作業...どのように結果が表示されている必要がありますか? 'Where'が複数回呼び出されていることを確認するためにデバッグしましたか? –

+1

それは事をする必要があるように見えます。ブレークポイントを入れてコードをステップ実行することから始めてください。 「言葉」の内容は何ですか? 'database.Log = Console.Out;'と入力して、出力ウィンドウで結果のSQLクエリを見ることもできます。あなたは何を期待していますか? –

+3

あなたはループ変数をクローズしています(http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx)クエリでwhere句を作成するときに使用します。したがって、効果的に最後の項目のみをフィルタリングします。 –

答えて

5

この試してみてください。これは、(ReSharperの少なくとも)「に変更クロージャへのアクセス」と呼ばれている

foreach(string word in words) 
{ 
    var temp = word; 
    result = result.Where(x => x.subject.Contains(temp)); 
} 

を - ラムダ式はをキャプチャしていない、彼らは変数全体をキャプチャします。また、ループの繰り返しごとに変数wordの値が変化しています。したがって、Where()メソッドは遅延評価されているので、このシーケンスが消費されるまでには、wordの値がシーケンスの最後の値になります。

+0

私はあなたのコードを試しましたが、複数の単語が入力されたときには何も表示されません.... – Daniel

+0

結果は最初の単語の結果に設定され、その後の検索は前の結果内のみを検索して上書きします... – Yahia

+0

thx Yahiaが、私の問題の解決策はありますか?どうすれば結果を絞り込むことができますか? – Daniel

0

それは事を行うことはできません - あなたは以前resultを上書きされているすべての単語を持つので、 - あなたは次のように何かをする必要があります:あなたの結果の型が故にList<object>で入力する内容

List<object> AllResults = new List<object>(); 

foreach(string word in words) 
{ 
    var temp = word; 
    AllResults.AddRange (result.Where(x => x.subject.Contains(temp)).ToList()); 
} 

わからないが。 ..

+0

申し訳ありませんが、私はIEnumerableで結果を得る必要があると私は知っていました。あなたの解決策の結果をIEnumerableに変換する方法がわかりません。 – Daniel

+0

ok - そして、私はあなたのコメントをもう一度見直す必要があると思います。私のソリューションを傷つけなさい...すべての結果レコードにすべての単語が必要な場合は、ポール・イクシスのソリューションを使用してください。 – Yahia

2

に私はこのようなロジックを反転させ、いくつかの成功をhade:

string[] words = enteredString.Split(); 

var results = from x in database.TableName 
       where words.Any(w => x.subject.Contains(w)) 
       select x; 

- 編集 より一般的なアプローチは、クエリのこの種のために、次のようになります。

class SearchQuery 
{ 
    public ICollection<string> Include { get; private set; } 
    public ICollection<string> Exclude { get; private set; } 
} 

[...] 
SearchQuery query = new SearchQuery 
{ 
    Include = { "Foo" }, Exclude = { "Bar" } 
} 

var results = from x in database.Table 
       where query.Include.All(i => x.Subject.Contains(i)) && 
        query.Exclude.All(i => !x.Subject.Contains(i)) 
       select x; 

これは、あなたがの少なくとも一つを持っているすべての科目を検索する場合query.Include内のすべての単語は、Subjectで発生しなければならないことを前提としてい私はEntity Framework 4でこれをテストしました。これはメモリではなくデータベースのすべての条件を適用するSQLクエリを作成します。ここで

+0

Tihonが動作していますが、別にコードを使用する方法を教えてください。結果を最初に取得してから、ソリューションを使用して結果を絞り込むことができます。 – Daniel

+0

@ダニエルあなたが 'words.Any'を' words.All'に変更したと思うのですが、それはトリックをする可能性があります –

+0

@Danielあなたは何をしようとしているのかについてもっと詳しく説明できますか? –

1

あなたが行く:

var result = from x in dataBase.tableName 
      select x; 

string[] words = enteredString.Split(); 
result.Where(r => words.Any(w => r.Subject.Contains(w)); 
+0

すべてのレコードを表示しています... – Daniel

関連する問題