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;
}

我正在将获取的数据转换为 List 以便我可以安全地说所有数据现在都在内存中?因此,在访问文件夹时,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)

我猜,但看起来你有一个文件夹表,其中子文件夹存储在同一个表中,ID 使用 FK 关系链接回父 ID?如果您有一个较深的文件夹层次结构,您可能最终会遇到递归问题,因为父母链接到孩子,链接到孩子,链接到孩子等等。我不知道 EF(对 EF 不太熟悉)会如何处理,但我猜这就是问题所在。

于 2012-07-14T02:25:21.663 回答