1

C#でエンティティコレクションのクエリ機能を使用すると、SQL Server 2008から関連レコードをロードするのに長い時間がかかります。これを行うための高速な方法はありますか?これは私が使用するクエリ関数です:

 public void SearchProducts()
    {
        //Filter by search string array(searchArray)
        List<string> prodId = new List<string>();

        foreach (string src in searchArray)
        {
            StoreProductCollection prod = new StoreProductCollection();
            prod.Query.Where(prod.Query.StptName.ToLower() == src.ToLower() && prod.Query.StptDeleted.IsNull());
            prod.Query.Select(prod.Query.StptName, prod.Query.StptPrice, prod.Query.StptImage, prod.Query.StptStoreProductID);
            //  prod.Query.es.Top = 4;
            prod.Query.Load();

            if (prod.Count > 0)
            {
                foreach (StoreProduct stpt in prod)
                {
                    if (!prodId.Contains(stpt.StptStoreProductID.ToString().Trim()))
                    {
                        prodId.Add(stpt.StptStoreProductID.ToString().Trim());
                        productObjectsList.Add(stpt);
                    }

                }
            }
         }
4

3 に答える 3

0

まず、StptName 列にインデックスを付けます。

次に、さらに優れたパフォーマンスが必要な場合は、ストアド プロシージャを SQL で記述してクエリを実行し、それを Entity Framework にマップします。

上記のいずれかを行う方法について説明が必要な場合はお知らせください。

ストアド プロシージャを記述したくない場合は、さらにいくつかのマイクロ最適化を行うことができます。

  1. 一時変数に src.ToLower() を書き込み、それと prod.Query.StptName.ToLower() を比較します。
  2. デフォルトでは、SQL Server クエリは大文字と小文字を区別しないため、そうであるかどうかを確認してください。そうである場合は、ToLower を完全に取り除くことができます。照合によって大文字と小文字の区別を変更できます。

編集:
インデックスを作成するには:
SQL Server Managment Studio でテーブル デザイナーを開きます。
任意の場所を右クリックして、[インデックス/キー] を選択します。
[追加] をクリックします。
[列] の下に StptName を追加します。
Is Unique で、StptName が一意かどうかを指定します。
タイプの下で「インデックス」を選択します。
それで全部です!

ストアド プロシージャのマッピングについては、次のような優れたチュートリアルがあります:
http://www.robbagby.com/entity-framework/entity-framework-modeling-select-stored-procedures/
("Select Stored のマップ手順」セクション)。

于 2012-07-17T08:51:25.833 に答える
0

アイテムごとに 1 回データベースにヒットしていますがsearchArray、これは非常に間違っています。次のようにすると、パフォーマンスが向上する可能性があります (テストする方法がないので、試してみてください)。

public void SearchProducts()
{
    //Filter by search string array(searchArray)
    List<string> prodId = new List<string>();
    StoreProductCollection prod = new StoreProductCollection();

    // Notice that your foreach() is gone

    // replace this
    // prod.Query.Where(prod.Query.StptName.ToLower() == src.ToLower() && prod.Query.StptDeleted.IsNull());
    // with this (or something similar: point is, you should call .Load() exactly once)
    prod.Query.where(prod.Query.StptDeleted.IsNull() && src.Any(srcArrayString => prod.Query.StptName.ToLower()==srcArrayString.ToLower());

    prod.Query.Select(prod.Query.StptName, prod.Query.StptPrice, prod.Query.StptImage, prod.Query.StptStoreProductID);
    //  prod.Query.es.Top = 4;
    prod.Query.Load();

    // ... rest of your code follows. 
}
于 2012-07-17T08:51:32.973 に答える
0

格下げList<string> searchArrayされた単語を含む場合:

    public void SearchProducts()  
    {  
        //Filter by search string array(searchArray)  
        List<string> prodId = new List<string>();

        StoreProductCollection prod = new StoreProductCollection();  
        prod.Query.Where(searchArray.Contains(prod.Query.StptName.ToLower()) && prod.Query.StptDeleted.IsNull());  
        prod.Query.Select(prod.Query.StptName, prod.Query.StptPrice, prod.Query.StptImage, prod.Query.StptStoreProductID);  
        //  prod.Query.es.Top = 4;  
        prod.Query.Load();  

        if (prod.Count > 0)  
        {  
            foreach (StoreProduct stpt in prod)  
            {  
                if (!prodId.Contains(stpt.StptStoreProductID.ToString().Trim()))  
                {  
                    prodId.Add(stpt.StptStoreProductID.ToString().Trim());  
                    productObjectsList.Add(stpt);  
                }  

            }  
        }  
     }  

このようにして、すべての単語に対して 1 つのクエリしかありません。

于 2012-07-17T08:52:00.523 に答える