DataView ile filtreleme (LINQ to DataSet)

Verileri belirli ölçütleri kullanarak filtreleme ve ardından kullanıcı arabirimi denetimi aracılığıyla verileri istemciye sunma özelliği, veri bağlamanın önemli bir yönüdür. DataView verileri filtrelemek ve belirli filtre ölçütlerini karşılayan veri satırlarının alt kümelerini döndürmek için çeşitli yollar sağlar. Dize tabanlı filtreleme özelliklerine ek olarak, DataView filtreleme ölçütleri için LINQ ifadelerini kullanma olanağı da sağlar. LINQ ifadeleri, dize tabanlı filtrelemeden çok daha karmaşık ve güçlü filtreleme işlemlerine olanak sağlar.

Kullanarak verileri DataViewfiltrelemenin iki yolu vardır:

  • DataView Where yan tümcesi ile LINQ'ten DataSet sorgusuna bir oluşturun.

  • 'nin var olan, dize tabanlı filtreleme özelliklerini DataViewkullanın.

Filtreleme Bilgileriyle Sorgudan DataView Oluşturma

LINQ DataView to DataSet sorgusundan nesne oluşturulabilir. Bu sorgu bir Where yan tümce içeriyorsa, DataView sorgudaki filtreleme bilgileriyle oluşturulur. yan tümcesindeki Where ifade, hangi veri satırlarının içinde yer alacaklarını DataViewbelirlemek için kullanılır ve filtrenin temelini oluşturur.

İfade tabanlı filtreler, daha basit dize tabanlı filtrelerden daha güçlü ve karmaşık filtreleme sunar. Dize tabanlı ve ifade tabanlı filtreler birbirini dışlar. Dize tabanlı RowFilter bir sorgudan oluşturulduktan sonra DataView ayarlandığında, sorgudan çıkarılan ifade tabanlı filtre temizlenir.

Not

Çoğu durumda, filtreleme için kullanılan ifadelerin yan etkileri olmamalıdır ve belirleyici olmalıdır. Ayrıca, filtreleme işlemleri birkaç kez yürütülebileceğinden, ifadeler belirli sayıda yürütmeye bağlı herhangi bir mantık içermemelidir.

Örnek

Aşağıdaki örnek, 2'den büyük ve 6'dan küçük olan siparişler için SalesOrderDetail tablosunu sorgular; bu sorgudan bir DataView oluşturur ve ' yi bire BindingSourcebağlarDataView:

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

Örnek

Aşağıdaki örnek, 6 Haziran 2001'den sonra verilen siparişler için bir sorgu oluşturur 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

Örnek

Filtreleme, sıralama ile de birleştirilebilir. Aşağıdaki örnek, soyadı "S" ile başlayan ve soyadına göre sıralanmış, ardından ad olarak sıralanmış kişiler için bir sorgu oluşturur 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()

Örnek

Aşağıdaki örnekte soyadı "Zhu" ile benzer olan kişileri bulmak için SoundEx algoritması kullanılmaktadır. SoundEx algoritması, SoundEx yönteminde uygulanır.

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, ilk olarak ABD Nüfus Sayımı Bürosu tarafından geliştirilen ve İngilizce olarak telaffuz edilen adları sese göre dizinleme için kullanılan fonetik bir algoritmadır. SoundEx yöntemi, İngilizce harf ve ardından üç sayı içeren bir ad için dört karakterlik bir kod döndürür. Harf, adın ilk harfidir ve sayılar addaki kalan ünsüzleri kodlar. Benzer seslendirme adları aynı SoundEx kodunu paylaşır. Önceki örneğin SoundEx yönteminde kullanılan SoundEx uygulaması burada gösterilmiştir:

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 Özelliğini Kullanma

'nin mevcut dize tabanlı filtreleme işlevi DataView LINQ to DataSet bağlamında çalışmaya devam ediyor. Dize tabanlı RowFilter filtreleme hakkında daha fazla bilgi için bkz . Verileri Sıralama ve Filtreleme.

Aşağıdaki örnek, Kişi tablosundan bir DataView oluşturur ve ardından özelliği, kişinin soyadının "Zhu" olduğu satırları döndürecek şekilde ayarlar 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 bir DataTable veya LINQ to DataSet sorgusundan oluşturulduktan sonra, sütun değerlerine göre satırların RowFilter alt kümelerini belirtmek için özelliğini kullanabilirsiniz. Dize tabanlı ve ifade tabanlı filtreler birbirini dışlar. özelliği ayarlandığında RowFilter LINQ'ten DataSet sorgusuna çıkarılacak filtre ifadesi temizlenir ve filtre ifadesi sıfırlanamaz.

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

Verilerin bir alt kümesinin dinamik görünümünü sağlamanın aksine, veriler üzerinde belirli bir sorgunun sonuçlarını döndürmek istiyorsanız, özelliğini ayarlamak RowFilter yerine veya FindRows yöntemlerini DataViewkullanabilirsinizFind. RowFilter özelliği en iyi şekilde, bağlı denetimin filtrelenmiş sonuçları görüntülediği veriye bağlı bir uygulamada kullanılır. özelliğinin RowFilter ayarlanması verilerin dizinini yeniden oluşturur, uygulamanıza ek yük ekler ve performansı azaltır. Find ve FindRows yöntemleri, dizinin yeniden oluşturulmasına gerek kalmadan geçerli dizini kullanır. Ya da FindRows yalnızca bir kez arayacaksanızFind, var olan DataViewöğesini kullanmanız gerekir. veya birden çok kez çağıracaksanızFind, aramak istediğiniz sütunda dizini yeniden oluşturmak için yeni DataView bir oluşturmalı ve ardından veya FindRows yöntemlerini çağırmalısınızFind.FindRows ve yöntemleri hakkında Find daha fazla bilgi için bkz. Satır Bulma ve DataView Performansı.FindRows

Filtreyi Temizleme

filtreleme özelliği kullanılarak RowFilter ayarlandıktan sonra üzerindeki DataView filtre temizlenebilir. üzerindeki DataView filtre iki farklı yolla temizlenebilir:

  • RowFilter özelliğini null olarak ayarlayın.

  • RowFilter özelliğini boş bir dize olarak ayarlayın.

Örnek

Aşağıdaki örnek bir sorgudan bir DataView oluşturur ve ardından özelliğini olarak ayarlayarak RowFilter filtreyi nulltemizler:

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

Örnek

Aşağıdaki örnek, bir tablodan özelliği DataView ayarlar RowFilter ve ardından özelliği boş bir dizeye ayarlayarak filtreyi RowFilter temizler:

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

Ayrıca bkz.