尝试在 Linq to Entities 中获取动态 order by 子句
Trying to get a dynamic order by clause in Linq to Entities
我正在尝试通过子句获得动态排序,但无法弄清楚语法。我以为我会用内联 if 语句破解它,但这些在 EF 中不受支持。
用户将能够 select 可能通过单击 dgv header.
要排序的字段(最初升序)
这是我的代码:-
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)
太棒了。这很可能会变得有些令人讨厌,并且可能会导致性能下降 SQL。读一读 https://use-the-index-luke.com/sql/where-clause/obfuscation/smart-logic(不是我想要 link 的博客 - 但我找不到我想要的那个,那看起来更老派了,就像曾经新闻网 post)
LINQ 中的查询是累积的,它们仅在发生枚举结果时 运行,例如对其调用 ToArray 或 ForEach
ing。这意味着您可以在多个 steps 中动态构建查询。 (为了 clarity/to 说明一点,我把事情简化了一点;我没有使用你的实际列名):
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 中的术语 AND 运算的一个。数据库查询在上面的任何一点都不是 运行,即使你添加了 OrderBy。如果您想了解更多信息,请查找 "LINQ deferred execution"。在您尝试读取结果的那一刻,查询将为 运行。
ps;我不确定我是否会让数据库进行排序,每次更改订单时都需要重新查询 - perhaps 只需将结果加载到知道如何排序的控件中(大多数网格控件, windows 和网络,知道如何缓存和排序他们的数据以避免往返于提供数据的地方),或者使用可以处理排序的客户端容器,例如DataTable、SortedList 等
我正在尝试通过子句获得动态排序,但无法弄清楚语法。我以为我会用内联 if 语句破解它,但这些在 EF 中不受支持。
用户将能够 select 可能通过单击 dgv header.
要排序的字段(最初升序)这是我的代码:-
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)
太棒了。这很可能会变得有些令人讨厌,并且可能会导致性能下降 SQL。读一读 https://use-the-index-luke.com/sql/where-clause/obfuscation/smart-logic(不是我想要 link 的博客 - 但我找不到我想要的那个,那看起来更老派了,就像曾经新闻网 post)
LINQ 中的查询是累积的,它们仅在发生枚举结果时 运行,例如对其调用 ToArray 或 ForEach
ing。这意味着您可以在多个 steps 中动态构建查询。 (为了 clarity/to 说明一点,我把事情简化了一点;我没有使用你的实际列名):
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 中的术语 AND 运算的一个。数据库查询在上面的任何一点都不是 运行,即使你添加了 OrderBy。如果您想了解更多信息,请查找 "LINQ deferred execution"。在您尝试读取结果的那一刻,查询将为 运行。
ps;我不确定我是否会让数据库进行排序,每次更改订单时都需要重新查询 - perhaps 只需将结果加载到知道如何排序的控件中(大多数网格控件, windows 和网络,知道如何缓存和排序他们的数据以避免往返于提供数据的地方),或者使用可以处理排序的客户端容器,例如DataTable、SortedList 等