1


1

NET WinFormsアプリケーションで「ビジネスオブジェクト」に対して単純な検索機能を提供するための最良の方法は何ですか?

「単純検索」とは、ほとんどすべてのウィンドウの右上隅にあるVista Windows 7の「検索ボックス」のようなものを意味します。それは簡単です。

「ビジネスオブジェクト」とは、「クライアント」や「アドレス」などのクラスに基づいたオブジェクトを意味します(ほとんどの場合は、単なる連絡先情報)

私は "ローリング私自身の"単純検索を考えていました。おそらく私のクラスに "Contains"関数を実装して、各オブジェクトにユーザーの検索語が含まれているかどうかを尋ねることができます。一致した単語数に基づきます。

私はLucene.NETについても調べましたが、私のニーズにとっては非常に複雑に思えます - インデックスを構築する(そしてそれを更新し維持する)必要があります。

提案? アイデア?

4 Answer


2


私は「最善の」方法について知りません(私がした場合、私はグーグルで働きます)。 それでも、数ヶ月前に概念実証/顧客デモで同様のことを実行したので、うまくいきました。 特にすぐに検索可能なデータセットのサイズに関しては、問題領域をかなり効果的に制限することができたので、パフォーマンスは問題にならなかったことに注意してください。

+ FilterableListView + http://msdn.microsoft.com/en-us/library/system.windows.forms.usercontrol.aspx [+ UserControl +]を作成しました。 詳細モードでhttp://msdn.microsoft.com/en-us/library/system.windows.forms.listview.aspx [+ ListView +]を使用し、http://msdn.microsoft.comを削除しました/en-us/library/system.windows.forms.textbox.aspx [+ TextBox +]のすぐ上にプラットフォーム相互運用機能を使用して、http://msdn.microsoft.com/en-us/library/bb761639を提供しました。 .aspx [CueText](「フィルター」または「検索」のようなもの)。 次に、バックグラウンドスレッドから「+ ListView 」の内容を更新しました(https://stackoverflow.com/questions/714666/is-it-appropriate-to-extend-control-to-provideの実装と同等のものを使用します) -consistently-safe-invoke-begininvo / 714680 [` SafeInvoke `])最後のhttp://msdn.microsoft.com/en-us/library/system.windows.forms.controlから0.5秒の遅延があった場合フィルターボックスからの.textchanged.aspx [` TextChanged +`]イベント。

`+ ListView +`の指定されたフィールドの内容に対して、大文字と小文字を区別しない単純な部分文字列の一致を行いました。これは、迅速、簡単、かつ効果的でした。 Linq to Objectsがとても便利であることがわかりました。

プロダクション対応の実装をもっと改善するために、いくつか改善したほうがよいでしょう。

  1. ダブルクリック速度を使用して、適切な遅延を計算してから 検索を実行します。

  2. ビルドする代わりに検索を実行するコールバックメカニズムを提供する コントロールに入れます。 おそらく、 `+ IFilterable +`インターフェースのようなものでしょうか?


0


インスタンスを記述する検索語のリストを返す単純なインターフェースをすべてのクラスに実装します。 それから、あなたはあなたのすべてのオブジェクトを取得し、それらの検索語を求め、そしてユーザー提供の検索語に基づいてそれらをランク付けすることができます。

これはContainsインターフェースの概念に近いですが、ビジネスクラスからロジックを除外します。 リフレクションを介してオブジェクトを調べることもできますし、検索エンジンに検索に含めるプロパティのヒントを与えるためにプロパティにユーザー属性を追加することもできます。

ただし、すべてのオブジェクトに対してすべての検索を評価する必要があることに注意してください。 複雑なランキング関数を使用すると、これは約100オブジェクトを超えると本当に遅くなります。 リフレクションを使用すると、状況はさらに悪くなります。

解決すべきもう1つの問題は、検索結果を意味のある方法で処理する方法です。 あなたがかなりの数の異なるクラスを持っているなら、結果を表示して、彼がそのオブジェクトで何かをすることができるアプリケーション内の場所にユーザをナビゲートすることは非自明のタスクかもしれません。


0


各オブジェクトで "Contains"メソッドを使用するというあなたのアプローチは非常に便利だと思います。

オブジェクトのメンバーに "* weight "を指定して、containsメソッドで一致が見つかった場合は、戻り値として " Score *"のようなものを指定できます。

考慮に入れるべき他の事はマッチが*完全なマッチであるかどうか*であるかどうかです…​ そして、そのスコアに多かれ少なかれポイントを割り当てます。

複数の種類のオブジェクトにわたって検索する場合 より高い優先度を与えるために、メインオブジェクト(よりビジネス中心のオブジェクト)により高い値を割り当てることができます。

ちょっと考えて…


0


あなたがあまりにも多くのオブジェクトを持っていない限り、それはあなたが説明していることをすることは理にかなっているでしょう、ただそれぞれのオブジェクトを通してループすることによって。 もう少し柔軟にするために、Containsの代わりに正規表現を使用することができます。 Containsは、オブジェクト内のプロパティの文字列値ではなく、オブジェクトに対する一致を示します。 文字列を一致させることはおそらくあなたにとってより役に立つでしょう。

できることの1つは、検索したいオブジェクト内のすべてのストリングを単に連結したストリングである、オブジェクト内のメソッドを作成することです。 次に、正規表現を適用してそのメソッドから得られる値を検索します。 それは簡単には最高のパフォーマンスの解決策にはなりませんが、それは迅速かつ簡単になるでしょう。 私が言ったように、あなたがあまりにも多くのオブジェクトを持っていない限り、それは大丈夫でしょう。