다음을 통해 공유


DataView를 사용하여 필터링(LINQ to DataSet)

특정 조건을 사용하여 데이터를 필터링한 다음 UI 컨트롤을 통해 클라이언트에 데이터를 표시하는 기능은 데이터 바인딩의 중요한 측면입니다. DataView 는 데이터를 필터링하고 특정 필터 조건을 충족하는 데이터 행의 하위 집합을 반환하는 여러 가지 방법을 제공합니다. 문자열 기반 필터링 기능 DataView 외에도 필터링 조건에 LINQ 식을 사용하는 기능도 제공합니다. LINQ 식을 사용하면 문자열 기반 필터링보다 훨씬 더 복잡하고 강력한 필터링 작업을 수행할 수 있습니다.

다음을 사용하여 데이터를 필터링하는 두 가지 방법이 있습니다.DataView

  • LINQ to DataSet 쿼리의 Where 절을 사용하여 DataView을(를) 만듭니다.

  • 의 기존 문자열 기반 필터링 기능을 DataView사용합니다.

필터링 정보를 사용하여 쿼리에서 DataView 만들기

DataView LINQ to DataSet 쿼리에서 개체를 만들 수 있습니다. 해당 쿼리에 Where 절이 포함된 경우, DataView이 쿼리의 필터링 정보를 사용하여 생성됩니다. 절의 Where 식은 필터에 포함될 DataView데이터 행을 결정하는 데 사용되며 필터의 기초입니다.

식 기반 필터는 더 간단한 문자열 기반 필터보다 더 강력하고 복잡한 필터링을 제공합니다. 문자열 기반 및 식 기반 필터는 상호 배타적입니다. 문자열 기반 RowFilter가 설정된 후, 쿼리에서 생성된 DataView로 인해 쿼리에서 유추된 식 기반 필터는 삭제됩니다.

비고

대부분의 경우 필터링에 사용되는 식에는 부작용이 없어야 하며 결정적이어야 합니다. 또한 필터링 작업이 여러 번 실행될 수 있으므로 식에는 설정된 실행 수에 따라 달라지는 논리가 포함되어서는 안 됩니다.

예시

다음 예제는 SalesOrderDetail 테이블에서 수량이 2보다 크고 6보다 작은 주문을 쿼리하고, 그 쿼리로부터 DataView를 생성한 후, DataViewBindingSource에 바인딩합니다.

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 속성을 설정하지 않고 FindRowsDataView 또는 RowFilter 메서드를 사용할 수 있습니다. 이 RowFilter 속성은 바인딩된 컨트롤이 필터링된 결과를 표시하는 데이터 바인딩된 애플리케이션에서 가장 적합합니다. 속성을 설정하면 RowFilter 데이터의 인덱스가 다시 작성되어 애플리케이션에 오버헤드가 추가되고 성능이 저하됩니다. 및 Find 메서드는 FindRows 인덱스를 다시 작성할 필요 없이 현재 인덱스를 사용합니다. 한 번만 호출 FindFindRows 하려는 경우 기존 DataView을 사용해야 합니다. Find 또는 FindRows을 여러 번 호출하려는 경우, 검색하려는 열의 인덱스를 다시 작성하기 위해 새로 DataView을 생성한 후 Find 또는 FindRows 메서드를 호출해야 합니다. FindFindRows 메서드에 대한 자세한 내용은 행 찾기데이터뷰 성능을 참조하세요.

필터 지우기

속성 DataView을 사용하여 RowFilter에서 필터링을 설정한 후 필터를 지울 수 있습니다. DataView의 필터는 두 가지 방법으로 크리어할 수 있습니다.

  • RowFilter 속성을 null으로 설정합니다.

  • RowFilter 속성을 빈 문자열로 설정합니다.

예시

다음 예제에서는 쿼리에서 DataView을(를) 생성하고, RowFilternull 속성을 설정하여 필터를 지웁니다.

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 = ""

참고하십시오