【问题标题】:Optimizing Search Results using LINQ使用 LINQ 优化搜索结果
【发布时间】:2013-01-11 04:55:10
【问题描述】:

我有一个使用分页的搜索。我的查询带回更多结果,然后我可以每页列出。我担心随着我的网站规模不断扩大,这可能会成为性能问题。我不确定如何有效地解决这个问题,并希望得到一些指导。下面是我调用来执行我的查询的方法。

   private List<dynamic> AdminSearchAll(string keyword)
        {
            string DDL = DDLAddDivision.SelectedValue;
            int DDLInt;
            int searchID = 0;

            if (int.TryParse(DDL, out DDLInt))
            {
                //int searchID;
                if (!int.TryParse(keyword, out searchID))
                    searchID = -1;  // set to an invalid ID
            }

            ItemContext db = new ItemContext();
            var contacts = (from c in db.Contacts
            join cat in db.Categories on c.CategoryID equals cat.CategoryID
            join div in db.Divisions on c.DivisionID equals div.DivisionID

                            where
                 (DDLInt == 1 || c.DivisionID == DDLInt) &&
                    (c.Deleted == false) &&
                                //Contains    
                    (
                     c.ContactName.Contains(keyword) ||
                     c.ContactEmail.Contains(keyword) ||
                     c.ContactOPhone.Contains(keyword) ||
                     c.ContactID.Equals(searchID)

                       )
                            select new
                            {

                                Name = c.ContactName,
                                Phone = c.ContactOPhone,
                                Type = c.Type,
                                Email = c.ContactEmail,
                                ID = c.ContactID

                            });
            var items = (from i in db.Item
            join cat in db.Categories on i.CategoryID equals cat.CategoryID
            join div in db.Divisions on i.DivisionID equals div.DivisionID
                         where
                           (DDLInt == 1 || i.DivisionID == DDLInt) &&
                           (i.Deleted == false) &&

                          //Contains

                     (
        i.ItemName.Contains(keyword) ||
        i.Email.Contains(keyword) ||
        i.Description.Contains(keyword) ||
        i.ItemID.Equals(searchID)
                      )
                         select new
                         {

                             Name = i.ItemName,
                             Phone = i.Phone,
                             Type = i.Type,
                             Email = i.Email,
                             ID = i.ItemID
                         });

            var all = contacts.Union(items);

            return all.ToList<dynamic>();

我使用 Asp.net Data Pager 进行分页。我每页显示 10 个结果。我的数据寻呼机使用了一个方法OnPreRender="Pager_PreRender"

protected void Pager_PreRender(object sender, EventArgs e)
        {
    if (IsPostBack)
                {


                        string keyword = txtSearch.Text.Trim();


                        List<dynamic> Cresults = AdminSearchAll(keyword);

    }
}

我的问题是使用 LINQ to SQL 将我的查询限制为仅返回十个结果的正确方法是什么,因为我分页而不是返回所有结果,并且由于寻呼机而仅显示 10 个。 PS 我为所有的代码道歉,但我想让你看看我在做什么。

【问题讨论】:

    标签: c# asp.net linq entity-framework ef-code-first


    【解决方案1】:

    您可以在 LINQ 级别实现分页,而不是将其委托给数据分页器,但需要进行一些重新编码。 LINQ 允许您执行 Skip-Take 操作,您可以在其中指定适当的页面大小以跳过和获取。

    有很多方法可以实现这一点,但由于这是我看到的代码的唯一部分,所以我建议这样做。

    1. 将您的页面大小和当前页面参数传递给您的搜索方法
    2. 排序您的列表,以便 LINQ 可以进行正确的分页
    3. 在订购后使用 Skip() 和 Take() 方法

    第 1 点

    private List<dynamic> AdminSearchAll(string keyword, int pageSize, int currentPage)
    

    搜索方法需要接受一个pageSize和currentPage参数,后面会用到。

    第 2 点

    var all = contacts.Union(items).OrderBy(a => a.Id);
    

    需要对您的列表进行排序,以便在成功调用该过程时,您仍然能够准确定位要提取的集合。

    第 3 点

    var all = contacts.Union(items).OrderBy(a => a.Id).Skip(pageSize * currentPage)
                      .Take(pageSize);
    

    Skip(int X) 方法告诉 LINQ 您要传递前 X 个条目。在这种情况下,我们跳过了 pageSize * currentPage。如果您位于第一页(索引 0),则不会跳过任何项目。 Take (int X) 方法告诉 LINQ,您只想从与您的页面大小相对应的起始索引中提取 X 个元素。

    当您返回“all.ToList()”时,它应该只包含您的 pageSize 参数中指定的元素。在您的主应用程序上,您应该能够轻松跟踪每个会话的 pageSize 和 currentPage。

    【讨论】:

    • 谢谢你,这是我试图做的,但无法实现。我猜你的集合int pageSize = 10 每页有 10 个结果。你也设置了int currentPage?这如何将List&lt;dynamic&gt; Cresults = AdminSearchAll(keyword); 更改为List&lt;dynamic&gt; Cresults = AdminSearchAll(keyword, pageSize, currentPage);
    • currentPage 允许您跟踪您在结果集中的位置。例如,如果您的页面大小为 10,并且您已经在第三页(即您单击“下一步”四次),那么 currentPage 将为 3。请记住,我们使用从零开始的索引,因此您的第一页load 是 currentPage 0。这将允许您通过 Skip(10 * 3) 跳过前 30 条记录。如果单击“上一个”,则 currentPage 将递减,因此您只需跳过前 20 条记录。 AdminSearchAll 确实可以按照您在此处所述的方式进行修改。
    • 谢谢,我的搜索工作按照我想要的方式进行,只是想弄清楚如何进行客户寻呼。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    相关资源
    最近更新 更多