【问题标题】:Trying to get a dynamic order by clause in Linq to Entities尝试在 Linq to Entities 中获取动态 order by 子句
【发布时间】:2020-05-04 17:30:03
【问题描述】:

我正在尝试使动态 order by 子句起作用,但无法弄清楚语法。以为我会用内联 if 语句破解它,但 EF 不支持这些。

用户可能通过单击 dgv 标题来选择要排序的字段(最初是升序)。

这是我的代码:-

Dim q = (From customer In db.tblcustomers.Where(Function(x) CBool(x.f_rn >= 0 And x.cu_brn = "00" _
    And (txtFiltAccno.Text.Trim = "" Or x.cu_accno.ToUpper.Contains(txtFiltAccno.Text.ToUpper.Trim)) _
    And (txtFiltCustName.Text.Trim = "" Or       x.cu_name.ToUpper.Contains(txtFiltCustName.Text.ToUpper.Trim)) _
    And (txtFiltPhone.Text.Trim = "" Or x.cu_telno.ToUpper.Contains(txtFiltPhone.Text.ToUpper.Trim)) _
    And (txtFiltFax.Text.Trim = "" Or x.cu_faxno.ToUpper.Contains(txtFiltFax.Text.ToUpper.Trim)) _
    And (txtFiltEmail.Text.Trim = "" Or x.cu_email.ToUpper.Contains(txtFiltEmail.Text.ToUpper.Trim))))
    select customer.f_rn, customer.cu_accno, customer.cu_name, customer.cu_add1, customer.cu_add2,     customer.cu_add3, customer.cu_add4, customer.cu_add5,
            customer.cu_telno, customer.cu_faxno, customer.cu_email).OrderBy(Function(u) 
IIf(a = "cu_name", u.cu_name,
IIf(a = "cu_add1", u.cu_add1,
IIf(a = "cu_add2", u.cu_add2,
IIf(a = "cu_add3", u.cu_add3,
IIf(a = "cu_add4", u.cu_add4,
IIf(a = "cu_add5", u.cu_add5,
IIf(a = "cu_telno", u.cu_telno,
IIf(a = "cu_faxno", u.cu_faxno,
IIf(a = "cu_email", u.cu_email, u.cu_accno)))))))))).Skip((pagenum - 1) * 25).Take(25)

【问题讨论】:

  • 谢谢,但用户可能希望根据多个条件进行搜索,例如显示在两个日期之间订购并发送到特定区域的所有蓝色小部件。
  • 另外我将查询限制为 25 条记录,因此在 dgv 上排序只会对这 25 条记录进行排序,而不是对整个表进行排序。据我所知,它必须是回到数据库的一次旅行,尤其是同时可能已经添加了新记录
  • 抱歉,我刚刚重读了您的消息,只是将查询分解,但要对查询运行分析器以查看它在做什么

标签: vb.net linq frameworks entity


【解决方案1】:

哎呀。这很可能会导致一些令人讨厌的,并且可能会降低 SQL 的执行速度。阅读https://use-the-index-luke.com/sql/where-clause/obfuscation/smart-logic(不是我想链接的博客——但我找不到我想的那个,那看起来更像老派,就像曾经是一篇usenet帖子)

LINQ 中的查询是累积的,它们仅在发生枚举结果时运行,例如在其上调用 ToArray 或 ForEaching 它。这意味着您可以通过几个步骤动态构建查询。 (为了清楚起见/为了说明一点,我把事情简化了一点;我没有使用你的实际列名):

Dim q as IEnumerable(Of Customer) = db.Customers

If nameTextBox.Text <> "" Then q = q.Where(Function(x) x.Name = nameTextBox.Text)

If ageTextBox.Text <> "" Then q = q.Where(Function(x) x.Age = ageTextBox.Text)

If jobTextBox.Text <> "" Then q = q.Where(Function(x) x.Age = jobTextBox.Text)

If sortByCombo.SelectedValue = "Name" Then q = q.OrderBy(Function(x) x.Name)
Else If ....

如果你只在Name 框中放了一些东西,q 就会调用一个Where。如果你在所有 3 个框中都放了一些东西,Where 是累积的,并且将作为一个在 SQL 中与术语 ANDed 一起使用。 db 查询在上述任何时候都不会运行,即使您添加了 OrderBy。如果您想了解更多信息,请查看“LINQ 延迟执行”。在您尝试读取结果的那一刻,将运行查询。

ps;我不确定我是否会让数据库进行排序,每次更改订单时都需要重新查询 - 也许只需将结果加载到知道如何排序的控件中(大多数网格控件、窗口和 web,知道如何缓存和排序他们的数据以避免往返到提供数据的地方),或者使用可以处理排序的客户端容器,例如一个 DataTable、SortedList 等

【讨论】:

    猜你喜欢
    • 2013-06-06
    • 2012-02-25
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多