ОБНОВЛЕНИЕ : ответ Груо был помечен как правильный, поскольку это была бы хорошая альтернатива.Я решил придерживаться операторов выбора / переключения, чтобы избежать проблем с производительностью использования отражения.Насколько я могу судить, нет способа сделать то, что я хочу, без использования Dynamic LINQ (и отражения) или декомпилятора (чтобы вручную кодировать каждый оператор LINQ, который я уже делаю вручную).Примечание: чтобы сделать это обновление, были удалены DropDownList16 через DropDownList20 (нужны символы).
Есть ли способ абстрагировать построение динамического запроса Linq to SQL?
попытка построить запрос Linq to SQL с динамическим предложением where на основе предоставленных пользователем фильтров.Пользователь должен иметь возможность фильтровать строки, целые числа и даты, используя расширенные параметры (равно, не равно, содержит, начинается с и т. Д.).Пользователь должен иметь возможность использовать эти фильтры с таким количеством или несколькими столбцами, как необходимо.
Мой текущий переключатель для одного столбца:
VB
Select Case type
Case StringFilterTypes.Any ''//Do nothing (same as else)
Case StringFilterTypes.Contains
query = From view In query Where view.Name.Contains(userValue) Select view
Case StringFilterTypes.Exactly
query = From view In query Where view.Name = userValue Select view
Case StringFilterTypes.StartsWith
query = From view In query Where view.Name.StartsWith(userValue) Select view
Case StringFilterTypes.EndsWith
query = From view In query Where view.Name.EndsWith(userValue) Select view
Case Else ''//Do nothing (same as Any).
End Select
C #
switch (type) {
case StringFilterTypes.Any: //Do nothing (same as else)
break;
case StringFilterTypes.Contains:
query = from view in querywhere view.Name.Contains(userValue)view;
break;
case StringFilterTypes.Exactly:
query = from view in querywhere view.Name == userValueview;
break;
case StringFilterTypes.StartsWith:
query = from view in querywhere view.Name.StartsWith(userValue)view;
break;
case StringFilterTypes.EndsWith:
query = from view in querywhere view.Name.EndsWith(userValue)view;
break;
default: //Do nothing (same as Any).
break;
}
Мне нужно будет использовать этот переключатель выбора / со всеми строковыми столбцами и аналогичный переключатель со всеми целочисленными столбцами и столбцами даты и времени.В результате я хочу превратить эти выборки / переключатели в функцию, в которой тип, view.Name и userValue являются переменными.Я могу передать type и userValue, так как они являются локальными переменными, но как я могу передать view.Name в функцию?
Я изучил расширения, но они, кажется, требуют, чтобы я передал view, уже знаю столбеци не поддерживают операторы select / switch.
Я также рассмотрел добавление операторов where в виде строк , но чувствую, что это устраняет только две причины для использования linq (проверенные компилятором запросы, автоматическое экранирование пользователявходные данные для предотвращения внедрения SQL).
Деревья выражений выглядят многообещающе, но я не уверен, как их использовать, и если они являются хорошей идеей, где производительность является проблемой.
Лучшее решение будет что-то вроде:
VB
Public Function ApplyFilters(query As IQueryable(Of DBName.ViewName)) As IQueryable(Of DBName.ViewName)
''//...
Filter_String (query, Type, View.Name, userValue)
''//...
End Function
Public Function Filter_String (query As IQueryable(Of DBName.ViewName), type As StringFilterTypes, column as ???, userValue As String) As IQueryable(Of DBName.ViewName)
Select Case type
Case StringFilterTypes.Any ''//Do nothing (same as else)
Case StringFilterTypes.Contains
query = From view In query Where column.Contains(userValue) Select view
Case StringFilterTypes.Exactly
query = From view In query Where column = userValue Select view
Case StringFilterTypes.StartsWith
query = From view In query Where column.StartsWith(userValue) Select view
Case StringFilterTypes.EndsWith
query = From view In query Where column.EndsWith(userValue) Select view
Case Else ''//Do nothing (same as Any).
End Select
Return query
End Function
C #
public IQueryable<DBName.ViewName> ApplyFilters(IQueryable<DBName.ViewName> query)
{
//...
Filter_String (query, Type, View.Name, userValue);
//...
}
public IQueryable<DBName.ViewName> Filter_String(IQueryable<DBName.ViewName> query, StringFilterTypes type, ??? column, string userValue)
{
switch (type) {
case StringFilterTypes.Any: //Do nothing (same as else)
break;
case StringFilterTypes.Contains:
query = from view in querywhere column.Contains(userValue)view;
break;
case StringFilterTypes.Exactly:
query = from view in querywhere column == userValueview;
break;
case StringFilterTypes.StartsWith:
query = from view in querywhere column.StartsWith(userValue)view;
break;
case StringFilterTypes.EndsWith:
query = from view in querywhere column.EndsWith(userValue)view;
break;
default:
break; //Do nothing (same as Any).
}
return query;
}
Обновление 2012/02/27:
ДляBlueRaja - Danny Pflughoeft Я предоставляю пример приложения.Очевидно, что соединение для передачи данных должно быть предоставлено конечным пользователем (база данных MS SQL с именем «Test» с таблицей с именем «testTable» и столбцами с именем «Column #», где # - это все числа 1–20).
Default.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication1.test._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList2" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList3" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList4" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox4" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList5" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox5" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList6" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox6" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList7" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox7" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList8" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox8" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList9" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox9" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList10" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox10" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList11" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox11" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList12" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox12" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList13" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox13" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList14" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox14" runat="server"></asp:TextBox>
<br />
<asp:DropDownList ID="DropDownList15" runat="server">
<asp:ListItem Selected="True" Text ="Any" Value="-1" />
<asp:ListItem Selected="False" Text ="Contains" Value="0" />
<asp:ListItem Selected="False" Text ="Is exactly" Value="1" />
<asp:ListItem Selected="False" Text ="Starts with" Value="2" />
<asp:ListItem Selected="False" Text ="Ends with" Value="3" />
</asp:DropDownList>
<asp:TextBox ID="TextBox15" runat="server"></asp:TextBox>
<br />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>
</form>
</body>
</html>
Default.aspx.vb
Public Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Protected Sub Page_LoadComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LoadComplete
Dim _db As TestDataContext = New TestDataContext(ConfigurationManager.ConnectionStrings("TestDataConn").ConnectionString)
Dim query As IQueryable(Of testTable) = _
From view In _db.testTables
Select view
Select Case DropDownList1.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column1.Contains(TextBox1.Text) Select view
Case "1"
query = From view In query Where view.Column1 = TextBox1.Text Select view
Case "2"
query = From view In query Where view.Column1.StartsWith(TextBox1.Text) Select view
Case "3"
query = From view In query Where view.Column1.EndsWith(TextBox1.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList2.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column2.Contains(TextBox2.Text) Select view
Case "1"
query = From view In query Where view.Column2 = TextBox2.Text Select view
Case "2"
query = From view In query Where view.Column2.StartsWith(TextBox2.Text) Select view
Case "3"
query = From view In query Where view.Column2.EndsWith(TextBox2.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList3.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column3.Contains(TextBox3.Text) Select view
Case "1"
query = From view In query Where view.Column3 = TextBox3.Text Select view
Case "2"
query = From view In query Where view.Column3.StartsWith(TextBox3.Text) Select view
Case "3"
query = From view In query Where view.Column3.EndsWith(TextBox3.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList4.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column4.Contains(TextBox4.Text) Select view
Case "1"
query = From view In query Where view.Column4 = TextBox4.Text Select view
Case "2"
query = From view In query Where view.Column4.StartsWith(TextBox4.Text) Select view
Case "3"
query = From view In query Where view.Column4.EndsWith(TextBox4.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList5.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column5.Contains(TextBox5.Text) Select view
Case "1"
query = From view In query Where view.Column5 = TextBox5.Text Select view
Case "2"
query = From view In query Where view.Column5.StartsWith(TextBox5.Text) Select view
Case "3"
query = From view In query Where view.Column5.EndsWith(TextBox5.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList6.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column6.Contains(TextBox6.Text) Select view
Case "1"
query = From view In query Where view.Column6 = TextBox6.Text Select view
Case "2"
query = From view In query Where view.Column6.StartsWith(TextBox6.Text) Select view
Case "3"
query = From view In query Where view.Column6.EndsWith(TextBox6.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList7.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column7.Contains(TextBox7.Text) Select view
Case "1"
query = From view In query Where view.Column7 = TextBox7.Text Select view
Case "2"
query = From view In query Where view.Column7.StartsWith(TextBox7.Text) Select view
Case "3"
query = From view In query Where view.Column7.EndsWith(TextBox7.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList8.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column8.Contains(TextBox8.Text) Select view
Case "1"
query = From view In query Where view.Column8 = TextBox8.Text Select view
Case "2"
query = From view In query Where view.Column8.StartsWith(TextBox8.Text) Select view
Case "3"
query = From view In query Where view.Column8.EndsWith(TextBox8.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList9.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column9.Contains(TextBox9.Text) Select view
Case "1"
query = From view In query Where view.Column9 = TextBox9.Text Select view
Case "2"
query = From view In query Where view.Column9.StartsWith(TextBox9.Text) Select view
Case "3"
query = From view In query Where view.Column9.EndsWith(TextBox9.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList10.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column10.Contains(TextBox10.Text) Select view
Case "1Column10"
query = From view In query Where view.Column10 = TextBox10.Text Select view
Case "2"
query = From view In query Where view.Column10.StartsWith(TextBox10.Text) Select view
Case "3"
query = From view In query Where view.Column10.EndsWith(TextBox10.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList11.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column11.Contains(TextBox11.Text) Select view
Case "1"
query = From view In query Where view.Column11 = TextBox11.Text Select view
Case "2"
query = From view In query Where view.Column11.StartsWith(TextBox11.Text) Select view
Case "3"
query = From view In query Where view.Column11.EndsWith(TextBox11.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList12.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column12.Contains(TextBox12.Text) Select view
Case "1"
query = From view In query Where view.Column12 = TextBox12.Text Select view
Case "2"
query = From view In query Where view.Column12.StartsWith(TextBox12.Text) Select view
Case "3"
query = From view In query Where view.Column12.EndsWith(TextBox12.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList13.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column13.Contains(TextBox13.Text) Select view
Case "1"
query = From view In query Where view.Column13 = TextBox13.Text Select view
Case "2"
query = From view In query Where view.Column13.StartsWith(TextBox13.Text) Select view
Case "3"
query = From view In query Where view.Column13.EndsWith(TextBox13.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList14.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column14.Contains(TextBox14.Text) Select view
Case "1"
query = From view In query Where view.Column14 = TextBox14.Text Select view
Case "2"
query = From view In query Where view.Column14.StartsWith(TextBox14.Text) Select view
Case "3"
query = From view In query Where view.Column14.EndsWith(TextBox14.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
Select Case DropDownList15.SelectedValue
Case "-1"
''//Do nothing (same as else)
Case "0"
query = From view In query Where view.Column15.Contains(TextBox15.Text) Select view
Case "1"
query = From view In query Where view.Column15 = TextBox15.Text Select view
Case "2"
query = From view In query Where view.Column15.StartsWith(TextBox15.Text) Select view
Case "3"
query = From view In query Where view.Column15.EndsWith(TextBox15.Text) Select view
Case Else
''//Do nothing (same as Any).
End Select
GridView1.DataSource = query
GridView1.DataBind()
End Sub
End Class