특정 조건을 사용하여 데이터를 필터링한 다음 UI 컨트롤을 통해 클라이언트에 데이터를 표시하는 기능은 데이터 바인딩의 중요한 측면입니다. DataView 는 데이터를 필터링하고 특정 필터 조건을 충족하는 데이터 행의 하위 집합을 반환하는 여러 가지 방법을 제공합니다. 문자열 기반 필터링 기능 DataView 외에도 필터링 조건에 LINQ 식을 사용하는 기능도 제공합니다. LINQ 식을 사용하면 문자열 기반 필터링보다 훨씬 더 복잡하고 강력한 필터링 작업을 수행할 수 있습니다.
다음을 사용하여 데이터를 필터링하는 두 가지 방법이 있습니다.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
예시
다음 예제에서는 2001년 6월 6일 이후에 주문된 주문에 대한 쿼리로부터 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
예시
필터링을 정렬과 결합할 수도 있습니다. 다음 예제에서는 성이 "S"로 시작하는 연락처를 대상으로 쿼리를 통해 DataView를 생성하고, 성과 이름 순으로 정렬합니다.
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 알고리즘을 사용하여 성이 "Zhu"인 연락처를 찾습니다. 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을 생성한 후, RowFilter 속성을 설정하여 연락처의 성이 "Zhu"인 행을 반환합니다.
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 또는 LINQ to DataSet 쿼리에서 DataTable가 만들어진 후, 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 인덱스를 다시 작성할 필요 없이 현재 인덱스를 사용합니다. 한 번만 호출 FindFindRows 하려는 경우 기존 DataView을 사용해야 합니다. Find 또는 FindRows을 여러 번 호출하려는 경우, 검색하려는 열의 인덱스를 다시 작성하기 위해 새로 DataView을 생성한 후 Find 또는 FindRows 메서드를 호출해야 합니다. Find 및 FindRows 메서드에 대한 자세한 내용은 행 찾기 및 데이터뷰 성능을 참조하세요.
필터 지우기
속성 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 = ""