Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La possibilità di filtrare i dati usando criteri specifici e quindi presentare i dati a un client tramite un controllo dell'interfaccia utente è un aspetto importante del data binding. DataView offre diversi modi per filtrare i dati e restituire subset di righe di dati che soddisfano criteri di filtro specifici. Oltre alle funzionalità di filtro basate su stringa, DataView offre anche la possibilità di usare espressioni LINQ per i criteri di filtro. Le espressioni LINQ consentono operazioni di filtro molto più complesse e potenti rispetto al filtro basato su stringhe.
Esistono due modi per filtrare i dati usando :DataView
Creare un oggetto DataView da una query LINQ to DataSet con una clausola Where.
Usare le funzionalità di filtro basate su stringhe esistenti di DataView.
Creazione di DataView da una query con informazioni di filtro
È possibile creare un oggetto da una query LINQ to DataSet DataView. Se la query contiene una Where
clausola , l'oggetto DataView viene creato con le informazioni di filtro della query. L'espressione nella Where
clausola viene usata per determinare quali righe di dati verranno incluse in DataViewe rappresenta la base per il filtro.
I filtri basati su espressioni offrono filtri più potenti e complessi rispetto ai filtri più semplici basati su stringhe. I filtri basati su stringa e basati su espressioni si escludono a vicenda. Quando la stringa basata su RowFilter viene impostata dopo la creazione di un oggetto DataView da una query, il filtro basato su espressione dedotto dalla query viene cancellato.
Annotazioni
Nella maggior parte dei casi, le espressioni usate per il filtro non devono avere effetti collaterali e devono essere deterministiche. Inoltre, le espressioni non devono contenere alcuna logica che dipende da un numero impostato di esecuzioni, perché le operazioni di filtro potrebbero essere eseguite un numero qualsiasi di volte.
Esempio
L'esempio seguente esegue una query sulla tabella SalesOrderDetail per gli ordini con una quantità maggiore di 2 e minore di 6; crea un oggetto DataView da tale query e associa l'oggetto DataView a un BindingSourceoggetto :
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
Esempio
Nell'esempio seguente viene creato un oggetto DataView da una query per gli ordini effettuati dopo il 6 giugno 2001:
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
Esempio
Il filtro può anche essere combinato con l'ordinamento. Nell'esempio seguente viene creato un oggetto DataView da una query per i contatti il cui cognome inizia con "S" e ordinato in base al cognome, quindi al nome:
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()
Esempio
Nell'esempio seguente viene usato l'algoritmo SoundEx per trovare i contatti il cui cognome è simile a "Zhu". L'algoritmo SoundEx viene implementato nel metodo 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 è un algoritmo fonetico usato per indicizzare i nomi in base al suono, come vengono pronunciati in inglese, originariamente sviluppato dal Census Bureau degli Stati Uniti. Il metodo SoundEx restituisce un codice di quattro caratteri per un nome costituito da una lettera inglese seguita da tre numeri. La lettera è la prima lettera del nome e i numeri codificano le consonanti rimanenti nel nome. Nomi che suonano simili condividono lo stesso codice SoundEx. L'implementazione SoundEx usata nel metodo SoundEx dell'esempio precedente è illustrata di seguito:
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
Utilizzo della proprietà RowFilter
La funzionalità di filtro basata su stringa esistente di DataView funziona ancora nel contesto LINQ to DataSet. Per altre informazioni sul filtro basato su RowFilter stringhe, vedere Ordinamento e filtro dei dati.
Nell'esempio seguente viene creato un oggetto DataView dalla tabella Contact e quindi viene impostata la RowFilter proprietà per restituire righe in cui il cognome del contatto è "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()
Dopo la creazione di un oggetto DataView da una DataTable query o LINQ to DataSet, è possibile utilizzare la RowFilter proprietà per specificare subset di righe in base ai relativi valori di colonna. I filtri basati su stringa e basati su espressioni si escludono a vicenda. L'impostazione della RowFilter proprietà cancella l'espressione di filtro dedotta dalla query LINQ to DataSet e l'espressione di filtro non può essere reimpostata.
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'"
Se si desidera restituire i risultati di una determinata query sui dati, anziché fornire una visualizzazione dinamica di un subset dei dati, è possibile utilizzare i Find metodi o FindRows di DataView, anziché impostare la RowFilter proprietà . La RowFilter proprietà viene usata meglio in un'applicazione associata a dati in cui un controllo associato visualizza i risultati filtrati. L'impostazione della RowFilter proprietà ricompila l'indice per i dati, aggiungendo un sovraccarico all'applicazione e riducendo le prestazioni. I Find metodi e FindRows usano l'indice corrente senza richiedere la ricompilazione dell'indice. Se si intende chiamare Find o FindRows una sola volta, è consigliabile usare l'oggetto esistente DataView. Se si intende chiamare Find o FindRows più volte, è necessario creare un nuovo DataView per ricompilare l'indice nella colonna su cui si vuole eseguire la ricerca e quindi chiamare i metodi Find o FindRows. Per altre informazioni sui Find metodi e FindRows , vedere Ricerca di righe e prestazioni di DataView.
Cancellazione del filtro
Il filtro su un DataView può essere pulito dopo che il filtro è stato impostato usando la proprietà RowFilter. Il filtro su un DataView può essere cancellato in due modi diversi:
Esempio
L'esempio seguente crea un oggetto DataView da una query e quindi cancella il filtro impostando la RowFilter proprietà su 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
Esempio
L'esempio seguente crea un oggetto DataView da una tabella imposta la RowFilter proprietà e quindi cancella il filtro impostando la RowFilter proprietà su una stringa vuota:
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 = ""