0

データベースからビジネス モデル エンティティを取得し、それらを繰り返して文字列を検索しようとしています。ただし、私のローカルホストでは、この操作には約7 to 9 seconds for 500 objects.

public List<FileFolder> SearchFolders(int id, string searchString) 
{
    /* Placeholder that references folders that passes search criteria */
    List<FileFolder> addedFolders = new List<FileFolder>();

    /* Get the folder with specified id, also include Folders
     * that this folder has. No problem here works perfectly fine
     * and fast */
    FileFolder folder = dbSet.Include("Folders").
                             .Where(q => q.FileFolderID == id)
                             .ToList().FirstOrDefault();

    /* This takes too much time as I mention, up to 9 seconds
     * for 500 Folders */
    foreach (FileFolder f in folder.Folders)
    {
       if (f.Name.Contains(searchString))
       {
           addedFolders.Add(f);
       }

    }
    return addedFolders;
}

取得したデータをリストに変換しているので、すべてのデータがメモリにあると安全に言えますか? そのため、foreach ループは、フォルダーへのアクセス中にこれ以上 db 呼び出しを行うべきではありません。また.Include、方法を確認しましたが、正常に機能しています。

この遅い反復の原因は何でしょうか?

ありがとう。

4

3 に答える 3

2

Foreach の代わりにこれを使用してみてください。

    if (folder!=null)
       {
           addedFolders.AddRange(folder.Folders.Where(f=>f.Name.Contains(searchString)));
       }

完全なコードは次のようになります。

public List<FileFolder> SearchFolders(int id, string searchString) 
{
    /* Placeholder that references folders that passes search criteria */
    List<FileFolder> addedFolders = new List<FileFolder>();

    /* Get the folder with specified id, also include Folders
     * that this folder has. No problem here works perfectly fine
     * and fast */
    FileFolder folder = dbSet.Include("Folders").
                             .Where(q => q.FileFolderID == id)
                             .FirstOrDefault();

    if (folder!=null)
    {
       addedFolders.AddRange(folder.Folders.Where(f=>f.Name.Contains(searchString)));
    }
    return addedFolders;
}
于 2012-07-14T00:07:22.547 に答える
1
/* This takes too much time as I mention, up to 9 seconds
 * for 500 Folders */

覚えておいてください、これは linq です。物事はすぐには起こりません。の最初の繰り返しの前にクエリの実行を実際に開始するわけではありませんforeach()

このクエリで本当に遅いのはこれです

FileFolder folder = dbSet.Include("Folders").
                         .Where(q => q.FileFolderID == id)
                         .FirstOrDefault();

問題は、dbSet の「フォルダ」がどのように定義されているかです。多くの FK 結合が組み込まれていますか? その場合、このような単純なリクエストでデータベース全体を取得できます。それはすべて、「フォルダー」に依存するものに依存します。

これはデバッガーでも確認できます。foreach ループをステップ オーバーすると、linq の行に「ポップ」して戻るのがわかります。

于 2012-07-14T02:55:11.767 に答える
0

あなたのラインについて:

foreach (FileFolder f in folder.Folders)

私は推測していますが、子フォルダーが同じテーブルに格納され、FK 関係を使用して ID が親 ID にリンクされている単一のフォルダー テーブルがあるように見えますか? フォルダー階層が深い場合、親が子にリンクする、子にリンクする、子にリンクするなどの再帰の問題が発生する可能性があります。EF (EF にあまり詳しくない) がそれをどのように処理するかはわかりません。 、しかし、問題はそこにあると思います。

于 2012-07-14T02:25:21.663 に答える