Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Возможность фильтровать данные с помощью определенных критериев, а затем представлять данные клиенту с помощью элемента управления пользовательским интерфейсом является важным аспектом привязки данных. DataView предоставляет несколько способов фильтрации данных и возвращать подмножества строк данных с определенными критериями фильтра. Помимо возможностей фильтрации на основе строк, DataView также предоставляет возможность использовать выражения LINQ для критериев фильтрации. Выражения LINQ позволяют выполнять гораздо более сложные и мощные операции фильтрации, чем фильтрация на основе строк.
Существует два способа фильтрации данных с помощью DataView:
Создайте DataView из запроса LINQ to DataSet с предложением Where.
Используйте существующие возможности DataViewфильтрации на основе строк.
Создание DataView из запроса с помощью сведений о фильтрации
Объект DataView можно создать из запроса LINQ to DataSet. Если этот запрос содержит Where
условие, DataView создается на основе сведений о фильтрации из запроса. Выражение в Where
условии используется для определения строк данных, которые будут включены в DataView, и является основой для фильтра.
Фильтры на основе выражений предлагают более мощные и сложные фильтры, чем более простые строковые фильтры. Фильтры на основе строк и выражений являются взаимоисключающими. Когда строковый RowFilter устанавливается после того, как DataView создан из запроса, фильтр на основе выражений, выведенный из запроса, очищается.
Замечание
В большинстве случаев выражения, используемые для фильтрации, не должны иметь побочных эффектов и должны быть детерминированными. Кроме того, выражения не должны содержать логику, которая зависит от заданного количества выполнений, так как операции фильтрации могут выполняться любое количество раз.
Пример
В следующем примере запрашивается таблица SalesOrderDetail для заказов с количеством, превышающим 2 и менее 6; создается DataView из этого запроса и DataView привязывается к BindingSource:
DataTable orders = _dataSet.Tables["SalesOrderDetail"];
EnumerableRowCollection<DataRow> query = from order in orders.AsEnumerable()
where order.Field<short>("OrderQty") > 2 && order.Field<short>("OrderQty") < 6
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Int16)("OrderQty") > 2 And _
order.Field(Of Int16)("OrderQty") < 6 _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
Пример
В следующем примере из запроса на заказы, размещенные после 6 июня 2001 года, создается DataView.
DataTable orders = _dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query = from order in orders.AsEnumerable()
where order.Field<DateTime>("OrderDate") > new DateTime(2002, 6, 1)
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 6, 1) _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
Пример
Фильтрация также может сочетаться с сортировкой. В следующем примере создается DataView на основе запроса для контактов, чьи фамилии начинаются с "S" и которые отсортированы сначала по фамилии, а затем по имени.
DataTable contacts = _dataSet.Tables["Contact"];
EnumerableRowCollection<DataRow> query = from contact in contacts.AsEnumerable()
where contact.Field<string>("LastName").StartsWith("S")
orderby contact.Field<string>("LastName"), contact.Field<string>("FirstName")
select contact;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName").StartsWith("S") _
Order By contact.Field(Of String)("LastName"), contact.Field(Of String)("FirstName") _
Select contact
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
Пример
В следующем примере используется алгоритм SoundEx для поиска контактов, фамилия которых похожа на "Чжу". Алгоритм SoundEx реализуется в методе SoundEx.
DataTable contacts = _dataSet.Tables["Contact"];
var soundExCode = SoundEx("Zhu");
EnumerableRowCollection<DataRow> query = from contact in contacts.AsEnumerable()
where SoundEx(contact.Field<string>("LastName")) == soundExCode
select contact;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim soundExCode As String = SoundEx("Zhu")
Dim query = _
From contact In contacts.AsEnumerable() _
Where SoundEx(contact.Field(Of String)("LastName")) = soundExCode _
Select contact
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
SoundEx — это фонетический алгоритм, используемый для индексирования имен по звуку, так как они произносится на английском языке, первоначально разработанный Бюро переписи населения США. Метод SoundEx возвращает четыре символьного кода для имени, состоящего из английского буквы, за которым следует три числа. Буква — это первая буква имени, а цифры кодируют оставшиеся консонанты в имени. Аналогичные имена звуков используют тот же код SoundEx. Реализация SoundEx, используемая в методе SoundEx предыдущего примера, показана здесь:
static string SoundEx(string word)
{
// The length of the returned code.
const int length = 4;
// Value to return.
var value = "";
// The size of the word to process.
var size = word.Length;
// The word must be at least two characters in length.
if (size > 1)
{
// Convert the word to uppercase characters.
word = word.ToUpper(CultureInfo.InvariantCulture);
// Convert the word to a character array.
var chars = word.ToCharArray();
// Buffer to hold the character codes.
var buffer = new StringBuilder
{
Length = 0
};
// The current and previous character codes.
var prevCode = 0;
var currCode = 0;
// Add the first character to the buffer.
buffer.Append(chars[0]);
// Loop through all the characters and convert them to the proper character code.
for (var i = 1; i < size; i++)
{
switch (chars[i])
{
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
case 'H':
case 'W':
case 'Y':
currCode = 0;
break;
case 'B':
case 'F':
case 'P':
case 'V':
currCode = 1;
break;
case 'C':
case 'G':
case 'J':
case 'K':
case 'Q':
case 'S':
case 'X':
case 'Z':
currCode = 2;
break;
case 'D':
case 'T':
currCode = 3;
break;
case 'L':
currCode = 4;
break;
case 'M':
case 'N':
currCode = 5;
break;
case 'R':
currCode = 6;
break;
}
// Check if the current code is the same as the previous code.
if (currCode != prevCode)
{
// Check to see if the current code is 0 (a vowel); do not process vowels.
if (currCode != 0)
{
buffer.Append(currCode);
}
}
// Set the previous character code.
prevCode = currCode;
// If the buffer size meets the length limit, exit the loop.
if (buffer.Length == length)
{
break;
}
}
// Pad the buffer, if required.
size = buffer.Length;
if (size < length)
{
buffer.Append('0', length - size);
}
// Set the value to return.
value = buffer.ToString();
}
// Return the value.
return value;
}
Private Function SoundEx(ByVal word As String) As String
Dim length As Integer = 4
' Value to return
Dim value As String = ""
' Size of the word to process
Dim size As Integer = word.Length
' Make sure the word is at least two characters in length
If (size > 1) Then
' Convert the word to all uppercase
word = word.ToUpper(System.Globalization.CultureInfo.InvariantCulture)
' Convert the word to character array for faster processing
Dim chars As Char() = word.ToCharArray()
' Buffer to build up with character codes
Dim buffer As StringBuilder = New StringBuilder()
' The current and previous character codes
Dim prevCode As Integer = 0
Dim currCode As Integer = 0
' Append the first character to the buffer
buffer.Append(chars(0))
' Loop through all the characters and convert them to the proper character code
For i As Integer = 1 To size - 1
Select Case chars(i)
Case "A", "E", "I", "O", "U", "H", "W", "Y"
currCode = 0
Case "B", "F", "P", "V"
currCode = 1
Case "C", "G", "J", "K", "Q", "S", "X", "Z"
currCode = 2
Case "D", "T"
currCode = 3
Case "L"
currCode = 4
Case "M", "N"
currCode = 5
Case "R"
currCode = 6
End Select
' Check to see if the current code is the same as the last one
If (currCode <> prevCode) Then
' Check to see if the current code is 0 (a vowel); do not process vowels
If (currCode <> 0) Then
buffer.Append(currCode)
End If
End If
' Set the new previous character code
prevCode = currCode
' If the buffer size meets the length limit, then exit the loop
If (buffer.Length = length) Then
Exit For
End If
Next
' Pad the buffer, if required
size = buffer.Length
If (size < length) Then
buffer.Append("0", (length - size))
End If
' Set the value to return
value = buffer.ToString()
End If
' Return the value
Return value
End Function
Использование свойства RowFilter
Существующие функции DataView фильтрации на основе строк по-прежнему работают в контексте LINQ to DataSet. Дополнительные сведения о фильтрации на основе RowFilter строк см. в разделе "Сортировка и фильтрация данных".
В следующем примере создается DataView из таблицы Contact, а затем задается свойство RowFilter, чтобы возвращать строки, в которых фамилия контакта — «Чжу».
DataTable contacts = _dataSet.Tables["Contact"];
DataView view = contacts.AsDataView();
view.RowFilter = "LastName='Zhu'";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
После создания DataView из запроса DataTable или LINQ to DataSet, можно использовать свойство RowFilter, чтобы указать подмножества строк, основанные на значениях столбцов. Фильтры на основе строк и выражений являются взаимоисключающими. Установка свойства RowFilter очистит выражение фильтра, построенное на основе запроса LINQ to DataSet, и выражение фильтра не может быть восстановлено.
DataTable contacts = _dataSet.Tables["Contact"];
EnumerableRowCollection<DataRow> query = from contact in contacts.AsEnumerable()
where contact.Field<string>("LastName") == "Hernandez"
select contact;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
view.RowFilter = "LastName='Zhu'";
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName") = "Hernandez" _
Select contact
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
view.RowFilter = "LastName='Zhu'"
Если вы хотите вернуть результаты определенного запроса к данным, а не предоставлять динамическое представление подмножества данных, можно использовать методы Find или FindRows из DataView, а не задавать свойство RowFilter. Свойство RowFilter лучше всего используется в приложении с привязкой к данным, где привязанный элемент управления отображает отфильтрованные результаты. RowFilter Задание свойства перестраивает индекс для данных, создавая дополнительную нагрузку на ваше приложение и уменьшая производительность. Методы Find и FindRows используют текущий индекс без необходимости перестраивать индекс. Если вы собираетесь вызвать Find или FindRows только один раз, следует использовать существующий DataView. Если вы собираетесь вызывать Find или FindRows несколько раз, необходимо создать новый DataView для перестроения индекса в столбце, по которому требуется выполнить поиск, а затем вызвать методы Find или FindRows. Дополнительные сведения о FindFindRowsметодах поиска строк и производительности DataView см. в разделе "Поиск строк" и " Производительность DataView".
Очистка фильтра
Фильтр в DataView можно очистить после применения фильтрации с помощью свойства RowFilter. Фильтр на объекте DataView можно очистить двумя разными способами:
Пример
В следующем примере из запроса создается DataView, а затем фильтр очищается путем установки свойства RowFilter в значение null
.
DataTable orders = _dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query = from order in orders.AsEnumerable()
where order.Field<DateTime>("OrderDate") > new DateTime(2002, 11, 20)
&& order.Field<decimal>("TotalDue") < new decimal(60.00)
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
view.RowFilter = null;
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 11, 20) _
And order.Field(Of Decimal)("TotalDue") < New Decimal(60.0) _
Select order
Dim view As DataView = query.AsDataView()
bindingSource1.DataSource = view
view.RowFilter = Nothing
Пример
В следующем примере создается DataView, исходя из таблицы, задается свойство RowFilter, а затем фильтр очищается, присваивая свойству RowFilter пустую строку.
DataTable contacts = _dataSet.Tables["Contact"];
DataView view = contacts.AsDataView();
view.RowFilter = "LastName='Zhu'";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
// Clear the row filter.
view.RowFilter = "";
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim view As DataView = contacts.AsDataView()
view.RowFilter = "LastName='Zhu'"
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
' Clear the row filter.
view.RowFilter = ""