ОБНОВЛЕНИЕ: Ответ Groo был отмечен как правильный, так как это была бы хорошая альтернатива. Я решил придерживаться утверждений select/switch, чтобы избежать проблем с использованием рефлексии. Насколько я могу судить, нет возможности делать то, что я хочу, не используя Dynamic LINQ (и отражение) или декомпилятор (чтобы вручную закодировать каждый оператор LINQ, который я уже делаю вручную). Примечание: чтобы это обновление DropDownList16 с помощью DropDownList20 было удалено (необходимы символы).Abstracting Dynamic Linq to SQL, где
Есть ли способ абстрагироваться от построения динамического запроса Linq to SQL?
Я пытаюсь построить запрос Linq to SQL с предложением dynamic 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;
}
мне нужно будет использовать этот выбор/выключатель со всеми строковых столбцов и подобный переключатель с все столбцы integer и datetime. В результате я хочу, чтобы эти атрибуты select/switch были включены в функцию, где переменные типа, view.Name и userValue. Я могу передать тип и userValue, поскольку они являются локальными переменными, но как я могу передать view.Name в функцию?
Я просмотрел расширения, но они, похоже, требуют, чтобы я проходил просмотр, знал колонку уже и не поддерживаю команды select/switch.
Я также рассмотрел adding the where statements as strings, но чувствую, что это устраняет только две причины для использования linq (запросы, связанные с компилятором, автоматическое экранирование ввода пользователя для предотвращения внедрения sql).
Expression Trees выглядят многообещающими, но я не уверен, как их использовать, и если они являются хорошей идеей, где производительность является проблемой.
Лучшим решением было бы что-то вроде:
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;
}
Update 2012/02/27:
Для BlueRaja - Дэнни 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.В.Б
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
Почему у вас есть фрагменты кода C# и VB.Net? На каком языке написан ваш настоящий код? – Groo
VB, но большинство людей больше знакомы с C#. Я соглашусь с C# или VB, я лучше с C# в любом случае. – Trisped
Почему вы хотите это сделать? Какое преимущество имеет значение 'Filter_String (query, StringFilterTypes.StartsWith, column, value)', просто используя 'query.Where (o => o.column.StartsWith (value))'? –