1

Web アプリケーション (C# の ASP.NET 4.0) があり、疑似 Adhoc コンポーネントを作成しています。このコンポーネントを使用すると、ユーザーは事前に定義されたカテゴリ (カー メーカー、ケア モデル、カー アクセサリーなど) のリストから選択できます。ユーザーは、必要な数のカテゴリを選択できます。[フィルタ] ボタンをクリックすると、選択したカテゴリが取得され、各カテゴリのオプションを含む新しいフォームに送信されます。各カテゴリには複数のオプションを含めることができます。

例: ユーザーが車の色、車のアクセサリーを選択します。

フィルター ページには、車の色の色が事前入力されたドロップダウンを含むフォームが表示されます。フォームには、サテライト ラジオ用のチェック ボックス、レザー インテリア用の別のチェック ボックスなどが表示されます。これらの値はすべて事前定義されています。ユーザーがフィルター処理できるすべてのアイテムを指定したら、Linq を使用してデータベースにクエリを実行します。現状では、Linq クエリは、現在 14 の左外部結合を保持するビューに対するものであり、まったくフィルター処理されていない場合、30,000 を超える行が返されます。

私は動的linqを使用してデータベースリンクにクエリを実行しています:

var data = CMS.Model.Adhoc.GetData().AsQueryable(); //must be AsQueryablefor Dynamic Linq to function

    public static List<ViewADHOCContractInfo> GetData()
    {
        PortalDataContext db = new PortalDataContext(AuthenticatedUser.ConnectionString);

        return db.ViewADHOCInfos.Select(x=>x).Distinct().ToList();
    }

GetData() は結果セットのすべての行とすべての列を返していることに注意してください。これは、これを行う最も効率的な方法ではないと思います。詳細については、下部で説明します。

そこから、送信されたフィルターで FOREACH ステートメントを実行し、各反復で結果セットを次のように最小化します (省略):

foreach (Filters filter in filters.OrderBy(x=>x.strOrderNumber))
        {
            SanatizeFilter(filter.strFilter,filter);
            if (filter.strValue != string.Empty && filter.strValue != null)
            {
                if (filter.strOperator == "Contains")
                {
                    data = data.Where(filter.strFilter + "!= NULL and " + filter.strFilter + ".Contains(@0)", filter.strValue).
                        Select(x => x).ToList().AsQueryable();
                }
                else
                {
                    data = data.Where(filter.strFilter + FormatOperator(filter.strOperator) + "@0", filter.strValue).
                        Select(x => x).ToList().AsQueryable();


                }
            }
        }

これはすべて正常に動作しますが、遅いです。私の最初の質問は、Linq を使用してこれを少し削減するにはどうすればよいかということです。事前入力の方法として、フィルターからのデータのみを変数「データ」にプルする方法をいくつか試しましたが、.AsQueryable() で動作させることはできません。すべてのオーバーヘッドに対処する必要がないように、フィルター オブジェクトから列識別子を取得し、データベースからそれらのみを選択できるようにしたいと考えていますが、それを可能にするソリューションが見つかりません。これを行う、何かアイデアはありますか?

2 番目の質問は、現在、これはすべてデータベースのビューにあります。関数またはストアド プロシージャに移動する方が高速/効率的でしょうか? Linq はストアド プロシージャと対話できますか?

前もって感謝します

4

1 に答える 1

1

さて、あなたの質問は2つの部分に分けることができます:

1)私のlinq-2-sqlアプローチは良いですか

2) データベースへのアプローチは適切か

最初の部分は、データベースに送信される SQL をプロファイリングすることで解決できます。これにより、実際に実行されたクエリが表示されます。コメントでわかるように、アプローチの早い段階で ToList() を使用すると、これは最適とはほど遠い可能性があります。データベースは、大規模なデータ セットのフィルタリングと処理に非常に優れています。だから、彼らが得意なことをやらせてください!

質問の 2 番目の部分は、ビューに関するものです。ストアドプロシージャなどを使用した方が速いでしょうか?質問の一部に答えるには: はい、Linq-2-sql はストアド プロシージャも使用できます。ただし、stored to プロシージャを使用して取得するデータが多すぎると、それでも遅くなります。これは、話の DBA 部分です。おそらく、ベース テーブルのいくつかのインデックスで十分でしょう。もう 1 つの方法は、クラスター化されたインデックスをビューに追加して、それを実体化することです。

最初に linq-2-sql 部分に対処することをお勧めします。実際に実行される sql がセットベースであり、すべてのフィルタリングがデータベースで行われていることを確認してください。それでも遅すぎる場合は、データベース層に移動して、そこで改善できる点を確認してください。

于 2012-06-20T16:41:56.837 に答える