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:
Örnek
Aşağıdaki örnek bir sorgudan bir DataView oluşturur ve ardından özelliğini olarak ayarlayarak RowFilter filtreyi null
temizler:
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 = ""